A __debug__
variável é útil em parte porque afeta todos os módulos. Se eu quiser criar outra variável que funcione da mesma maneira, como eu faria isso?
A variável (sejamos originais e chamemos de 'foo') não precisa ser verdadeiramente global, no sentido de que se eu mudar de foo em um módulo, ela será atualizada em outros. Eu ficaria bem se pudesse definir foo antes de importar outros módulos e eles veriam o mesmo valor para ele.
hasattr(__builtin__, "foo")
.Se você precisar de uma variável global entre módulos, talvez apenas uma variável simples no nível de módulo seja suficiente.
a.py:
b.py:
c.py:
Teste:
Exemplo do mundo real: global_settings.py do Django (embora nas configurações dos aplicativos Django sejam usadas importando o objeto
django.conf.settings
).fonte
a.py
, contivermain()
? Isso importa?if __name__=="__main__"
guard nele para evitar a execução de código inesperado na importação.id()
para verificar a identidade)Acredito que há muitas circunstâncias em que isso faz sentido e simplifica a programação para que alguns globais sejam conhecidos em vários módulos (fortemente acoplados). Nesse espírito, gostaria de elaborar um pouco a idéia de ter um módulo de globais importado pelos módulos que precisam fazer referência a eles.
Quando existe apenas um desses módulos, chamo-o de "g". Nele, atribuo valores padrão para cada variável que pretendo tratar como global. Em cada módulo que usa qualquer um deles, eu não uso "from g import var", pois isso resulta apenas em uma variável local que é inicializada a partir de g somente no momento da importação. Eu faço a maioria das referências na forma g.var e "g". serve como um lembrete constante de que estou lidando com uma variável potencialmente acessível a outros módulos.
Se o valor de uma variável global desse tipo for usado com freqüência em alguma função de um módulo, essa função poderá fazer uma cópia local: var = g.var. No entanto, é importante perceber que as atribuições para var são locais e o g.var global não pode ser atualizado sem fazer referência explicitamente ao g.var em uma atribuição.
Observe que você também pode ter vários módulos globais compartilhados por diferentes subconjuntos de seus módulos para manter as coisas um pouco mais controladas. O motivo de eu usar nomes abreviados para meus módulos globais é evitar sobrecarregar muito o código com as ocorrências deles. Com apenas um pouco de experiência, eles se tornam mnemônicos o suficiente com apenas 1 ou 2 caracteres.
Ainda é possível fazer uma atribuição para, digamos, gx quando x já não foi definido em g, e um módulo diferente pode acessar gx No entanto, mesmo que o intérprete permita, essa abordagem não é tão transparente e evito isto. Ainda existe a possibilidade de criar acidentalmente uma nova variável em g como resultado de um erro de digitação no nome da variável para uma atribuição. Às vezes, um exame de dir (g) é útil para descobrir nomes de surpresa que possam ter surgido por esse acidente.
fonte
Defina um módulo (chame-o de "globalbaz") e tenha as variáveis definidas dentro dele. Todos os módulos que usam esse "pseudoglobal" devem importar o módulo "globalbaz" e fazer referência a ele usando "globalbaz.var_name"
Isso funciona independentemente do local da alteração, você pode alterar a variável antes ou depois da importação. O módulo importado usará o valor mais recente. (Eu testei isso em um exemplo de brinquedo)
Para esclarecimento, o globalbaz.py é assim:
fonte
Você pode passar as globais de um módulo para outro:
No módulo A:
No módulo B:
fonte
Variáveis globais geralmente são uma má ideia, mas você pode fazer isso atribuindo a
__builtins__
:Além disso, os próprios módulos são variáveis que você pode acessar de qualquer módulo. Portanto, se você definir um módulo chamado
my_globals.py
:Então você pode usar isso de qualquer lugar também:
Usar módulos em vez de modificar
__builtins__
geralmente é uma maneira mais limpa de fazer globals desse tipo.fonte
__builtins__
é uma peculiaridade CPython, você realmente não deve usá-lo - melhor utilização__builtin__
(oubuiltins
em Python3) como a resposta aceita espectáculosVocê já pode fazer isso com variáveis no nível do módulo. Os módulos são os mesmos, independentemente do módulo do qual estão sendo importados. Assim, você pode tornar a variável uma variável no nível do módulo em qualquer módulo que faça sentido colocá-la e acessá-la ou atribuí-la a partir de outros módulos. Seria melhor chamar uma função para definir o valor da variável ou torná-la uma propriedade de algum objeto singleton. Dessa forma, se você precisar executar algum código quando a variável for alterada, poderá fazê-lo sem interromper a interface externa do seu módulo.
Normalmente, não é uma ótima maneira de fazer as coisas - usar globals raramente é - mas acho que essa é a maneira mais limpa de fazer isso.
fonte
Eu queria postar uma resposta dizendo que há um caso em que a variável não será encontrada.
As importações cíclicas podem interromper o comportamento do módulo.
Por exemplo:
first.py
second.py
main.py
Neste exemplo, deve ser óbvio, mas em uma grande base de código, isso pode ser realmente confuso.
fonte
Isso parece modificar o
__builtin__
espaço para nome. Para fazer isso:Não use o
__builtins__
diretamente (observe os "s" extras)) - aparentemente, este pode ser um dicionário ou um módulo. Obrigado a ΤΖΩΤΖΙΟΥ por apontar isso, mais pode ser encontrado aqui .Agora
foo
está disponível para uso em qualquer lugar.Eu não recomendo fazer isso geralmente, mas o uso disso depende do programador.
A atribuição a ele deve ser feita como acima, apenas a configuração
foo = 'some-other-value'
o definirá no espaço de nomes atual.fonte
Eu uso isso para algumas funções primitivas internas que eu senti que estavam realmente faltando. Um exemplo é uma função find que possui a mesma semântica de uso que filter, map, red.
Depois que isso é executado (por exemplo, importando próximo ao seu ponto de entrada), todos os seus módulos podem usar find () como se, obviamente, ele estivesse embutido.
Nota: Você pode fazer isso, é claro, com filtro e outra linha para testar o comprimento zero ou reduzir em um tipo de linha estranha, mas sempre achei que era estranho.
fonte
Eu poderia obter variáveis modificáveis (ou mutáveis ) entre módulos usando um dicionário:
Ao iniciar
test_wait_app_up_fail
, a duração real do tempo limite é de 3 segundos.fonte
Perguntei-me se seria possível evitar algumas das desvantagens do uso de variáveis globais (veja, por exemplo, http://wiki.c2.com/?GlobalVariablesAreBad ) usando um espaço de nome de classe em vez de um espaço de nome global / módulo para passar valores de variáveis . O código a seguir indica que os dois métodos são essencialmente idênticos. Há uma pequena vantagem no uso de namespaces de classe, conforme explicado abaixo.
Os fragmentos de código a seguir também mostram que atributos ou variáveis podem ser criados e excluídos dinamicamente nos espaços de nomes globais / de módulo e de classe.
wall.py
Eu chamo esse módulo de 'parede', pois ele é usado para devolver variáveis. Ele atuará como um espaço para definir temporariamente variáveis globais e atributos de toda a classe do 'roteador' da classe vazia.
source.py
Este módulo importa parede e define uma única função
sourcefn
que define uma mensagem e a emite por dois mecanismos diferentes, um via global e outro via função de roteador. Observe que as variáveiswall.msg
ewall.router.message
são definidas aqui pela primeira vez em seus respectivos namespaces.dest.py
Este módulo define uma função
destfn
que usa os dois mecanismos diferentes para receber as mensagens emitidas pela fonte. Permite a possibilidade de a variável 'msg' não existir.destfn
também exclui as variáveis depois que elas são exibidas.main.py
Este módulo chama as funções definidas anteriormente em sequência. Após a primeira chamada para
dest.destfn
as variáveiswall.msg
ewall.router.msg
não existe mais.A saída do programa é:
global: Olá mundo!
roteador: Olá mundo!
global: nenhuma mensagem
roteador: nenhuma mensagem
Os fragmentos de código acima mostram que os mecanismos de módulo / global e de variável de classe / classe são essencialmente idênticos.
Se muitas variáveis devem ser compartilhadas, a poluição do namespace pode ser gerenciada usando vários módulos do tipo parede, por exemplo, wall1, wall2 etc. ou definindo várias classes do tipo roteador em um único arquivo. O último é um pouco mais organizado, então talvez represente uma vantagem marginal para o uso do mecanismo de variável de classe.
fonte