Sempre usei este método:

from sys import argv 

e use argv com apenas argv . Mas há uma convenção de usar isso:

import sys 

e usar o argv por sys.argv

O segundo método torna o código autodocumentado e eu (realmente) aderi a ele. Mas a razão pela qual prefiro o primeiro método é que ele é rápido porque estamos importando apenas a função necessária, em vez de importar o módulo inteiro (que contém mais funções inúteis que o python perderá tempo importando-as). Observe que preciso apenas do argv e todas as outras funções do sys são inúteis para mim.

Então, minhas perguntas são. O primeiro método realmente torna o script mais rápido? Qual método é mais preferido? Por quê?

Comentários

Resposta

Importar o módulo não desperdiça nada ; o módulo é sempre totalmente importado (para o mapeamento sys.modules), então se você usar import sys ou from sys import argv não faz diferença.

A única diferença entre as duas declarações é o nome que está vinculado; import sys vincula o nome sys para o módulo (então sys -> sys.modules["sys"]), enquanto from sys import argv liga um nome diferente, argv, apontando diretamente para o atributo contido dentro do módulo (então argv -> sys.modules["sys"].argv). O resto do O módulo e sys ainda está lá, quer você use alguma coisa do módulo ou não.

Também não há diferença de desempenho entre as duas abordagens. Sim, sys.argv precisa pesquisar duas coisas; ele precisa procurar sys em seu namespace global (encontra o módulo) e, em seguida, procurar o atributo argv. E sim, usando from sys import argv você pode pular a pesquisa de atributo, uma vez que você já tem uma referência direta ao atributo. Mas a instrução import ainda precisa fazer esse trabalho, ela procura o mesmo atributo durante a importação e você “só precisará usar argv uma vez . Se você tivesse que usar argv milhares de vezes em um loop, talvez pudesse fazer a diferença, mas neste caso específico realmente não faz .

A escolha entre um ou outro deve ser baseada no estilo de codificação .

Em um módulo grande , Eu certamente usaria import sys; a documentação do código é importante e o uso de sys.argv em um módulo grande torna muito mais claro a que você está se referindo do que apenas argv faria.

Se o único lugar que você usar argv for um "__main__" bloco para chamar um main() função, por suposto use from sys import argv se você se sentir mais feliz com isso:

if __name__ == "__main__": from sys import argv main(argv) 

I “d ainda uso import sys lá eu mesmo. Todas as coisas sendo iguais (e são, exatamente, em termos de desempenho e número de caracteres usados para escrevê-lo) , isso é apenas mais fácil para mim.

Se você estiver importando algo diferente por completo, talvez o desempenho entre em jogo. Mas apenas se você usar um nome específico em um módulo muitas vezes , em um loop crítico, por exemplo. Mas criar um nome local (dentro de uma função) será ainda mais rápido:

 import somemodule def somefunction(): localname = somemodule.somefunctionorother while test: # huge, critical loop foo = localname(bar) 

Comentários

  • Também há a situação em que você tem um pacote com subpacotes ou módulos que expõe um atributo de um desses subpacotes / módulos no pacote de nível superior. Usar from...import permite que você faça package.attribute em vez de package.subpackage_or_module.attribute, o que pode ser útil se você tem agrupamentos lógicos ou conceituais dentro do pacote, mas deseja tornar as coisas um pouco mais convenientes para os usuários do seu pacote. (numpy faz algo assim, eu acredito.)
  • No django você tem muitos locais onde coisas como from django.core.management.base import BaseCommand são melhores e qualquer outra coisa (especialmente import django) levaria a um código ilegível. Portanto, embora eu goste dessa resposta, acho que existem algumas bibliotecas (e especialmente alguns frameworks) nas quais a convenção é violar a importação básica.Como sempre, use seu julgamento sobre o que é melhor em uma determinada situação. Mas erre pelo lado explícito (em outras palavras, concordo na maior parte).
  • @JAB: você ainda pode usar import ... as para encontrar o pacote para um nome diferente: import package.subpackage_or_module as shortname. from parent import sub faz, essencialmente, a mesma coisa.
  • so wether you use import sys or from sys import argv makes no odds este parece não ser o caso com o IDLE. apenas importar o módulo não importa suas funções e posso chamá-lo no shell IDLE apenas por < módulo >. < function > nome
  • @Suncatcher: leia minha resposta por completo. A frase que você cita fala sobre quanto está sendo importado, não qual nome está vinculado. Isso ‘ é coberto em outra parte da resposta.

Resposta

Há duas razões a favor do uso de import module em vez de from module import function.

O primeiro é o namespace. Importar uma função para o namespace global arrisca colisões de nomes.

Em segundo lugar, não é tão relevante para os módulos padrão, mas significativo para seus próprios módulos, especialmente durante o desenvolvimento. É a opção de reload() um módulo. Considere o seguinte:

from module import func ... reload(module) # func still points to the old code 

Por outro lado

import module ... reload(module) # module.func points to the new code 

Quanto à velocidade .. .

estamos importando apenas a função necessária, em vez de importar o módulo inteiro (que contém mais funções inúteis que o python perderá tempo importando-as)

Independentemente de você importar um módulo ou importar uma função de um módulo, o Python analisará todo o módulo. De qualquer forma, o módulo é importado. “Importar uma função” nada mais é do que vincular a função a um nome. Na verdade, import module dá menos trabalho para o intérprete do que from module import func.

Comentários

  • reload () era um embutido no Python 2; esse não é mais o caso do Python 3.
  • Achei que também havia implicações relacionadas às dependências de importação circulares?

Resposta

Eu uso from import s sempre que melhora a legibilidade. Por exemplo, eu prefiro (ponto-e-vírgulas são apenas para economizar espaço aqui):

from collections import defaultdict from foomodule import FooBar, FooBaz from twisted.internet.protocol import Factory defaultdict(); FooBar(); FooBaz(); Factory() 

em vez de:

import collections import foomodule import twisted.internet.protocol collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz() twisted.internet.protocol.Factory() 

O último é mais difícil de ler (e escrever) para mim porque contém muitas informações redundantes. Além disso, é útil saber com antecedência quais partes de um módulo estou usando.

Eu prefiro import s regulares se estou usando muitos de nomes curtos de um módulo:

import sys sys.argv; sys.stderr; sys.exit() 

Ou se um nome for tão genérico que não faça sentido fora de seu namespace:

import json json.loads(foo) from json import loads loads(foo) # potentially confusing 

Comentários

  • Esta é minha resposta favorita. ‘ Explícito é melhor do que implícito ‘ às vezes entra em conflito com legibilidade, simplicidade e DRY. Especialmente ao usar uma estrutura como Django.

Resposta

Na minha opinião, usando melhora a legibilidade. Ao revisar o código Python, gosto de ver de onde vem a função ou classe fornecida exatamente de onde é usada. Isso me poupa de rolar para o topo do módulo para obter essa informação.

Quanto aos nomes de módulo longos, eu apenas uso a palavra-chave as e forneço-lhes breves aliases:

import collections as col import foomodule as foo import twisted.internet.protocol as twip my_dict = col.defaultdict() foo.FooBar() twip_fac = twip.Factory() 

Como exceção, sempre uso a notação from module import something quando lido com __future__. Você simplesmente não pode fazer de outra maneira quando deseja que todas as strings sejam Unicode por padrão no Python 2, por exemplo,

from __future__ import unicode_literals from __future__ import print_function 

Comentários

  • Amém! ” importar porque ” é uma combinação vencedora 🙂

Resposta

Embora import sys e from sys import agrv ambos importam todo o módulo sys, o último usa vinculação de nome para que apenas o módulo argv esteja acessível para o restante do código.

Para algumas pessoas, este seria o estilo preferido, pois torna acessível apenas a função que você declarou explicitamente.

No entanto, introduz conflitos de nomes em potencial. E se você tivesse outro módulo chamado argv? Observe que você também pode importar explicitamente a função e renomear com from sys import argv as sys_argv, uma convenção que atende à importação explícita e é menos provável de fornecer espaço de nome colisões.

Comentários

  • Então, como if sys_argv: é melhor do que if sys.argv:? Eu sei o que a segunda afirmação significa, não tenho ideia do que a primeira forma significa sem voltar para a importação bizarra.

Resposta

Recentemente, fiz esta pergunta para mim mesmo. Cronometrei os diferentes métodos.

Solicita a biblioteca

def r(): import requests return "hello" timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop def rg(): from requests import get return "hello" timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop 

biblioteca beautifulsoup

def bs(): import bs4 return "hello" timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop def be(): from bs4 import BeautifulSoup return "hello" timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop 

biblioteca json

def js(): import json return "hello" timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop def jl(): from json import loads return "hello" timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop 

biblioteca sys

def s(): import sys return "hello" timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop def ar(): from sys import argv return "hello" timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop 

Parece que me que uma ligeira diferença no desempenho.

Comentários

  • Você está adicionando em uma pesquisa de atributo. Para comparar import module com from module import name corretamente, adicione essa pesquisa de nome ao import module caso. Por exemplo. adicione a linha sys.argv ao ar teste, etc. Ainda haverá uma diferença, porque o trabalho realizado é ligeiramente diferente, conforme bytecode diferente é gerado e codepaths diferentes são executados.
  • Observe que eu abordo diretamente essa diferença em minha resposta; haverá uma diferença entre usar import sys e usar sys.argv milhares de vezes em um loop vs. from sys import argv em seguida, usando apenas argv. Mas você não ‘ t. Para coisas que você faz apenas uma vez no nível global do seu módulo, você realmente deve otimizar para legibilidade, não diferenças microscópicas de tempo.
  • Ahhhh! E eu pensei que estava no caminho certo! 🙂 Eu apenas esqueci sua resposta. Parece que eu me precipitei nessa. É bom sentir-se humilde.

Resposta

Examinando fragmentos de código publicados, importando módulos inteiros e referindo-se a module.function é praticamente o padrão, pelo menos para módulos padrão. A única exceção parece ser datetime

from datetime import datetime, timedelta 

então você pode dizer datetime.now() em vez de datetime.datetime.now().

Se você está preocupado com o desempenho, pode sempre dizer (por exemplo)

argv = sys.argv 

e, em seguida, faça seu código crítico de desempenho, uma vez que a pesquisa do módulo já foi feita. No entanto, embora isso funcione com funções / métodos, a maioria dos IDE se confundirá e não exibirá (por exemplo) um link / assinatura de origem para a função quando for atribuída a uma variável.

Resposta

Só quero acrescentar que se você fizer algo como

from math import sin 

(ou qualquer outra biblioteca integrada como sys ou posix), então sin ser incluído na documentação do seu módulo (ou seja, quando você fizer >>> help(mymodule) ou $ pydoc3 mymodule. Para evitar isso, importe usando:

import math from math import sin as _sin 

PS: uma biblioteca integrada é aquela compilada a partir do código C e incluída no Python. argparse, os e io não são pacotes integrados

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *