Como obter uma referência a um módulo dentro do próprio módulo?

158

Como posso obter uma referência a um módulo nesse módulo? Além disso, como posso obter uma referência ao pacote que contém esse módulo?

Ram Rachum
fonte
7
Eu suspeito que você possa estar fazendo esta pergunta porque possui uma variável no escopo do módulo (por exemplo, BLAH = 10 fora de uma função ou classe), depois uma variável de classe / função chamada BLAH e deseja diferenciar. Uma pergunta válida aqui é: isso é necessário? As regras de escopo são notoriamente propensas a erros, especialmente pelo 'idiota' que pega seu código depois de você (ou seja, você, seis meses depois). Truques como esse raramente são necessários; Eu tento evitá-los completamente porque eles são muitas vezes confusos e modificados incorretamente mais tarde.
Kevin J. Rice,
2
@ KevinJ.Rice "o 'idiota' que pega seu código depois que você (ou seja, você, seis meses depois)" fez o meu dia!
Arctelix
8
Quem se importa por que ele está fazendo a pergunta? Existem várias razões válidas para fazer isso.
Christopher Barber
Precisa ser fechado. Muito útil.
mlvljr 17/03

Respostas:

211
import sys
current_module = sys.modules[__name__]
truppo
fonte
3
exceto que isso não estará correto se o módulo for recarregado; Eu não acho que exista um lugar onde seja garantida uma referência, se houver, recarregar não funcionaria, certo?
Dima Tisnek
14
Recarregar reutiliza o mesmo objeto de módulo; nenhum novo objeto de módulo é criado; portanto, ele ainda está correto diante do recarregamento.
bukzor
18

Mais uma técnica, que não importa o módulo sys, e sem dúvida - depende do seu gosto - mais simples:

current_module = __import__(__name__)

Esteja ciente de que não há importação. Python importa cada módulo apenas uma vez.

Uri
fonte
Essa parece ser uma maneira muito boa de evitar a importação de sistemas. Além de ser um pouco contra-intuitivo de ler, existem possíveis desvantagens nessa abordagem?
JeremyDouglass
@JeremyDouglass. Não que eu saiba. A importação é uma função interna legítima, documentada (a única função xx ). Você pode substituí-lo pelo pacote 'importlib' (você precisará importá-lo). Talvez - nunca tenha acontecido comigo - você possa ter um problema com a importação relativa / absoluta, se um módulo com o mesmo nome estiver disponível no sys.path; nesse caso, você poderá resolvê-lo com o argumento 'level' da função.
Uri
16

Se você tem uma classe nesse módulo, a __module__propriedade da classe é o nome do módulo da classe. Assim, você pode acessar o módulo via sys.modules[klass.__module__]. Isso também funciona para funções.

Michael
fonte
4
Na verdade, parece que (pelo menos) para uma função, a __module__propriedade não é um módulo, mas uma string; portanto, uma inspect.getabsfile(func.__module__)falha com " TypeError: 'os' não é um objeto de módulo, classe, método, função, rastreamento, quadro ou código "; enquanto inspect.getabsfile(sys.modules[o.__module__])parece passar.
Sdaau #
12

Você pode obter o nome do módulo atual usando __name__

A referência do módulo pode ser encontrada no sys.modulesdicionário.

Veja a documentação do Python

pkit
fonte
1

Você pode passá-lo de fora:

mymod.init(mymod)

Não é o ideal, mas funciona para o meu caso de uso atual.

Sam Watkins
fonte