2016-01-04 3 views
2

Резюме: У меня есть скрипт, который выставляет (1) в dict и мне нужно, чтобы изменить это dict от того, с другим модулемКак изменить значение модульной переменной из объекта другого модуля?

Примечание: Два больших ответов на similar question объяснить много о переменных обзорного между модулями, но я не понимаю, как это относится к моему делу.

В приведенном ниже коде я ожидал, что смогу изменить переменную mainmodule.pycontainer с точностью до submodule.py, что не так. Зачем?

Как я могу обратиться к mainmodule экземпляру container с точностью до submodule?

Код для основного сценария

# mainmodule.py 
# the main script which ultimately exposes the module variable 'container' 
import submodule 

container = dict() 

class MainClass: 
    def __init__(self): 
     self.sub = submodule.SubClass() 

    def set(self, number): 
     print("main: container was {container}".format(container=container)) 
     container['x'] = number 
     print("main: container is {container}".format(container=container)) 


    def call(self, number): 
     self.sub.set(number) 

if __name__ == "__main__": 
    mc = MainClass() 
    # updating container from this script 
    mc.set(1) 
    # updating container from another module 
    mc.call(2) 
    # again from this script, to check the updates 
    mc.set(3) 

Код для импортируемого модуля

# submodule.py 
import mainmodule 

class SubClass: 
    def __init__(self): 
     pass 

    def set(self, number): 
     print("sub: container was {container}".format(container=mainmodule.container)) 
     mainmodule.container['x'] = number 
     print("sub: container is {container}".format(container=mainmodule.container)) 

Выход

main: container was {} 
main: container is {'x': 1} 
sub: container was {} 
sub: container is {'x': 2} 
main: container was {'x': 1} 
main: container is {'x': 3} 

(1) Реальный код использует bottle предоставить container через json.dumps()

+0

Вы можете явно передать ссылку на 'container' каждому из методов, которые его мутируют – dm03514

+0

Вы имеете в виду http://stackoverflow.com/questions/29701972/python-global-variables-in-multiple-files/29702401 # 29702401? –

ответ

4

Посмотрев на свой код немного, я думаю, что знаю, что может вас отбросить. Сценарий python, вызванный как python foo.py, будет являться модулем (в sys.modules), который называется __main__. Это означает, что нижний бит ваших шоу mainmodule.py загружается и компилируется и запускается один раз с __name__ == "__main__", что приводит к некоторым вещам. Этот модуль импортирует submodule, который еще не импортирован, чтобы он загружался и запускался.

submodule в свою очередь пытается импортировать mainmodule. Хотя этот файл был выполнен раньше, он не известен интерпретатору этим именем модуля, поэтому mainmodule.py снова запускается, на этот раз с __name__ == "mainmodule" (что не совпадает с "__main__", поэтому снимок if внизу снижается).

Это означает, что у вас есть две копии container, один в модуле чье имя является __main__, и один в модуле с именем mainmodule. Тот факт, что оба из файла, называемого ./mainmodule.py, не имеет отношения к делу.

Есть несколько способов исправить это. Одна из них всегда импорта реальный сразу, как:

# mainmodule.py 
import submodule 
class Foo: 
    pass 
if __name__ == "__main__": 
    import mainmodule 
    mainmodule.Foo() 

Другой вариант заключается в перемещении кода внутри if в другой файл.