No Python, depois de importar um módulo X em uma sessão de intérprete usando import X
, e as mudanças do módulo na parte externa, posso recarregar o módulo com reload(X)
. As alterações ficam disponíveis na minha sessão de intérprete.
Estou me perguntando se isso também é possível quando importo um componente Y do módulo X usando from X import Y
.
A instrução reload Y
não funciona, pois Y não é um módulo em si, mas apenas um componente (neste caso, uma classe) dentro de um módulo.
É possível recarregar componentes individuais de um módulo sem sair da sessão do intérprete (ou importar o módulo inteiro)?
EDITAR:
Para esclarecimento, a questão é sobre como importar uma classe ou função Y de um módulo X e recarregar em uma mudança, não um módulo Y de um pacote X.
fonte
... possible ... import a component Y from module X
" vs "question is ... importing a class or function X from a module Y
". Estou adicionando uma edição para esse efeito.Respostas:
Se Y for um módulo (e X um pacote)
reload(Y)
estará bem - caso contrário, você verá porque bons guias de estilo Python (como o do meu empregador) dizem para nunca importar nada, exceto um módulo (este é um dos muitos grandes motivos - mas as pessoas ainda manter a importação de funções e classes diretamente, não importa o quanto eu explico que é não uma boa ideia ;-).fonte
import this
do prompt interativo para ver o Zen do Python); e todas as razões pelas quais os namespaces são uma ótima ideia (pistas visuais locais imediatas de que o nome está sendo pesquisado, facilidade de simulação / injeção em testes, capacidade de recarregar, capacidade de um módulo mudar de maneira flexível redefinindo algumas entradas, previsível e controlável comportamento na serialização e recuperação de seus dados [[por exemplo, por decapagem e retirada da separação]] e assim por diante - um comentário SO dificilmente é longo o suficiente para fazer justiça a este argumento longo e rico !!! -)importlib
pacote.importlib.reload(Y)
docs.python.org/3.4/library/… veja também stackoverflow.com/questions/961162/…Responda
Em meus testes, a resposta marcada, o que sugere um simples
reload(X)
, não funciona.Pelo que posso dizer, a resposta correta é:
Teste
Meu teste foi o seguinte (Python 2.6.5 + bpython 0.9.5.2)
X.py:
bpython:
fonte
Foo
que tem um__init__.py
que busca um submódulo ... Vou postar uma resposta como contra-exemplo.fonte
Em primeiro lugar, você não deve usar reload de forma alguma, se puder evitá-lo. Mas vamos supor que você tenha seus motivos (ou seja, depuração dentro do IDLE).
Recarregar a biblioteca não levará os nomes de volta ao namespace do módulo. Para fazer isso, basta reatribuir as variáveis:
Você poderia fazer isso de algumas outras maneiras. Você poderia automatizar o processo pesquisando no namespace local e reatribuindo qualquer coisa que fosse do módulo em questão, mas acho que estamos sendo malvados o suficiente.
fonte
Se você quiser fazer isso:
Em vez disso:
Agora você pode usar myobject da mesma maneira que estava planejando (sem as cansativas referências ilegíveis de mymodule em todos os lugares).
Se você está trabalhando interativamente e deseja recarregar myobject de mymodule, agora você pode usar:
fonte
presumindo que você usou
from X import Y
, você tem duas opções:ou
algumas considerações:
A. se o escopo de importação não for de todo o módulo (por exemplo: importar em uma função) - você deve usar a segunda versão.
B. se Y é importado para X de outro módulo (Z) - você deve recarregar Z, recarregar X e recarregar seu módulo, mesmo recarregando todos os seus módulos (por exemplo, usando
[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
) pode recarregar X antes de recarregar Z - e então não atualize o valor de Y.fonte
reload()
móduloX
,reload()
módulo importandoY
deX
.Observe que o recarregamento não altera os objetos já criados vinculados a outros namespaces (mesmo se você seguir o guia de estilo de Alex).
fonte
Se você estiver trabalhando em um ambiente jupyter, e você já tem
from module import function
pode usar a função mágica,autoreload
porA introdução do
autoreload
em IPython é fornecida aqui .fonte
Só para acompanhar AlexMartelli do e do Catskul respostas, existem alguns casos muito simples, mas desagradáveis que aparecem para confundir
reload
, pelo menos em Python 2.Suponha que eu tenha a seguinte árvore de origem:
com o seguinte conteúdo:
init.py:
bar.py:
Isso funciona bem sem usar
reload
:Mas tente recarregar e não terá efeito ou corromperá as coisas:
A única maneira de garantir que o
bar
submódulo fosse recarregado erareload(foo.bar)
; a única maneira de acessar aQuux
classe recarregada é alcançá-la e pegá-la do submódulo recarregado; mas ofoo
próprio módulo manteve oQuux
objeto de classe original , presumivelmente porque ele usafrom bar import Bar, Quux
(ao invés deimport bar
seguido porQuux = bar.Quux
); além disso, aQuux
classe saiu de sincronia consigo mesma, o que é simplesmente bizarro.fonte