Статическая переменная Python - PullRequest
2 голосов
/ 24 ноября 2011

Я создаю приложение, которое использует базовый класс для хранения всех значений конфигурации, методов импорта и т. Д.

/
  - application.py
      + class foo
            + config = None
            + def loadconfig
  - otherfile.py
      + class bar
            + def getconfigvalue

Итак, если я запускаю application.py, и он запускает loadconfig, который загружает значение в foo.config, а затем импортирует (внутри указанной функции - для обхода циклического импорта) otherfile.py и создает новый bar object, который затем пытается получить значение конфигурации из foo.config, но говорит, что foo.config равно None. Есть предложения?

Упрощенный код:
main.py

class Main:
    config = None
    @staticmethod
    def start():
        ## Load the configuration from a file, creating a dict in Main.config ##
        Main.other()

    @staticmethod
    def other():
        from otherfile import otherclass
        otherclass()

Main.start()

otherfile.py

from main import Main
class otherclass:
    def __init__(self):
        print(Main.config) ## Prints "None"

Примечание: это было устроено так, потому что именно так оно и работает в программе; Я чувствую, что это как-то связано с областью действия

Полные исходные файлы:
asgard.py: http://pastebin.com/jRkWzrPq
library / childcontainer.py: http://pastebin.com/6a561Nun

1 Ответ

4 голосов
/ 24 ноября 2011

Я буду работать, как я полагаю, ваша проблема связана с asgard, потому что ваш упрощенный пример не работает:

  1. Вы не можете запустить main.py из-за циклического импорта, но я верюэто был main.py, который вы намеревались запустить (запуск otherfile.py не вызовет проблемы, с которой, я полагаю, вы столкнетесь).
  2. На самом деле вы никогда ничего не назначаете на Main.config.Я не уверен точно, где вы намеревались присвоить ему.

В любом случае, на asgard.py.

Здесь вы столкнетесь с проблемой модуля __main__,Когда вы запускаете asgard.py, его __name__ равно __main__;что-то, о чем вы можете не знать, это то, что это буквально имя модуля, как оно появляется в sys.modules - основной модуль - sys.modules['__main__'], а не sys.modules['asgard'].Затем, когда вы импортируете library.childcontainer, он пытается импортировать asgard.Это ищет sys.modules['asgard'], который не существует, и поэтому импортирует содержимое asgard.py в новый объект модуля.

Если бы у вас был другой файл main.py, который сделал import asgard; asgard.Asgard.initialize()(игнорируя проблему условного импорта, о которой я упомяну ниже), вы не столкнетесь с этой проблемой, потому что модуль __main__ будет с этим main.py, а asgard.py будет импортирован только с именем asgard.Другое решение, которое будет работать, было бы if __name__ == '__main__': sys.modules['asgard'] = sys.modules['__main__'].

И, пожалуйста, , пожалуйста, , , пожалуйста, , не , , потяните это if __name__ == '__main__': import ....трюк.Это означает, что, например, если вы попытаетесь набрать import asgard; asgard.Asgard.initialize(), произойдет сбой, сказав, что имя 'os' не определено.Пожалуйста, поместите эти импорта в начало файла, где они принадлежат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...