os.path
funciona de uma maneira engraçada. Parece que os
deveria ser um pacote com um submódulo path
, mas, na realidade, os
é um módulo normal que faz mágica com sys.modules
a injeção os.path
. Aqui está o que acontece:
Quando o Python é iniciado, ele carrega vários módulos sys.modules
. Eles não estão vinculados a nenhum nome no seu script, mas você pode acessar os módulos já criados quando importá-los de alguma forma.
sys.modules
é um ditado no qual os módulos são armazenados em cache. Quando você importa um módulo, se ele já foi importado em algum lugar, ele obtém a instância armazenada sys.modules
.
os
está entre os módulos carregados quando o Python é iniciado. Ele atribui seu path
atributo a um módulo de caminho específico do sistema operacional.
Ele injeta sys.modules['os.path'] = path
para que você possa fazer " import os.path
" como se fosse um submódulo.
Eu costumo pensar os.path
como um módulo que eu quero usar, e não como algo no os
módulo , portanto, mesmo que não seja realmente um submódulo de um pacote chamado os
, importo-o como se fosse um e sempre façoimport os.path
. Isso é consistente com a os.path
documentação.
Aliás, esse tipo de estrutura leva a muitas confusões iniciais dos programadores de Python sobre módulos e pacotes e organização de códigos, eu acho. Isso é realmente por duas razões
Se você pensa os
em um pacote e sabe que pode fazer import os
e ter acesso ao submódulo os.path
, poderá se surpreender mais tarde quando não puder fazer import twisted
e acessar automaticamente twisted.spread
sem importá-lo.
É confuso que os.name
é uma coisa normal, uma string e os.path
é um módulo. Eu sempre estruturo meus pacotes com __init__.py
arquivos vazios para que, no mesmo nível, eu sempre tenha um tipo de coisa: um módulo / pacote ou outra coisa. Vários grandes projetos Python adotam essa abordagem, que tende a criar código mais estruturado.
import os.path
mim mesmo e acho que é uma maneira melhor. Por "Isso é consistente com a documentação do os.path", quis dizer que ele recebe sua própria página na documentação em docs.python.org/library/os.path.html .os.py
fato se injetasys.modules['os.path']
. Então é por isso quefrom os.path import something
realmente funciona. Fiquei curioso sobre quando isso foi introduzido e verifiquei a fonte. Curiosidade: Isso é de 1999, incluído pela primeira vez no Python 1.5.2. O commit original está aqui .Conforme PEP-20 de Tim Peters, "Explícito é melhor que implícito" e "Legibilidade conta". Se tudo que você precisa do
os
módulo estiver abaixoos.path
,import os.path
seria mais explícito e deixaria outras pessoas saberem com o que você realmente se importa.Da mesma forma, o PEP-20 também diz "Simples é melhor que complexo"; portanto, se você também precisar de coisas que residam sob o
os
guarda - chuva mais geral ,import os
seria preferido.fonte
import os
é realmente ser "simples" de maneira significativa. Simples! = Curto.import os
e umimport os.path
é idiota se você por exemplo, necessidadeos.getcwd()
eos.path.isfile()
Resposta definitiva:
import os
e useos.path
. nãoimport os.path
diretamente.A partir da documentação do próprio módulo:
fonte
os.path
módulo que não existe, mas paraposixpath
."Instead of importing this module directly, import os and refer to this module as os.path."
está localizado emposixpath.py
(oumacpath.py
,ntpath.py
etc.). Estou bastante certo de que o que eles querem dizer é que não se deveimport posixpath
(o que funciona), mas sim importar o módulo viaos
para melhor portabilidade. Eu não acho que eles pretendem dar uma recomendação sobre se éimport os
ouimport os.path
não preferido.Curiosamente, a importação do os.path importará todo o os. tente o seguinte no prompt interativo:
O resultado será o mesmo que se você tivesse importado os. Isso ocorre porque o os.path se refere a um módulo diferente com base em qual sistema operacional você possui, portanto, o python importará o os para determinar qual módulo carregar para o caminho.
referência
Em alguns módulos, o ditado
import foo
não será expostofoo.bar
, então acho que depende realmente do design do módulo específico.Em geral, apenas importar os módulos explícitos necessários deve ser um pouco mais rápido. Na minha máquina:
import os.path
:7.54285810068e-06
segundosimport os
:9.21904878972e-06
segundosEstes tempos estão próximos o suficiente para serem razoavelmente insignificantes. Seu programa pode precisar usar outros módulos
os
agora ou mais tarde; portanto, geralmente faz sentido sacrificar os dois microssegundos e usá-loimport os
para evitar esse erro posteriormente. Eu costumo lado apenas importando os como um todo, mas posso ver por que alguns preferemimport os.path
ser tecnicamente mais eficientes e transmitir aos leitores do código que essa é a única parte doos
módulo que precisará ser usada. Essencialmente, tudo se resume a uma questão de estilo em minha mente.fonte
from os import path
tornará as chamadas para o caminho ainda mais rápidas se a velocidade for o problema.O senso comum funciona aqui:
os
é um módulo e tambémos.path
é um módulo. Portanto, basta importar o módulo que você deseja usar:Se você deseja usar funcionalidades no
os
módulo, importeos
.Se você deseja usar funcionalidades no
os.path
módulo, importeos.path
.Se você deseja usar funcionalidades nos dois módulos, importe os dois módulos:
Para referência:
Lib / idlelib / rpc.py usa
os
e importaos
.Lib / idlelib / idle.py usa
os.path
e importaos.path
.Lib / assegurarpip / init .py usa os dois e importa os dois.
fonte
Não foi possível encontrar nenhuma referência definitiva, mas vejo que o código de exemplo para os.walk usa os.path, mas importa apenas os
fonte