Использование глобальных переменных между файлами?

Я немного смущен тем, как работают глобальные переменные. У меня большой проект с около 50 файлами, и мне нужно определить глобальные переменные для всех этих файлов.

Что я сделал, это определить их в моих проектах main.py, как показано ниже:

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

Я пытаюсь использовать myList в subfile.py, как показано ниже

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
    globals()["myList"].append("hey")

Другим способом я попытался, но не работал ни

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

И внутри subfile.py у меня было это:

# ../myproject/subfile.py

# Import globfile
import globfile

# Save "hey" into myList
def stuff():
    globfile.myList.append("hey")

Но опять же это не сработало. Как мне это реализовать? Я понимаю, что он не может работать так, когда эти два файла действительно не знают друг друга (нужный подфайл не знает основную информацию), но я не могу придумать, как это сделать, без использования io письма или рассола, который Я не хочу этого делать.

Ответ 1

Проблема в том, что вы определили myList из main.py, но subfile.py должен использовать его. Вот простой способ решить эту проблему: переместить все глобальные переменные в файл, я называю этот файл settings.py. Этот файл отвечает за определение глобалов и их инициализацию:

# settings.py

def init():
    global myList
    myList = []

Затем ваш subfile может импортировать глобальные переменные:

# subfile.py

import settings

def stuff():
    settings.myList.append('hey')

Обратите внимание, что subfile не вызывает init() - эта задача принадлежит main.py:

# main.py

import settings
import subfile

settings.init()          # Call only once
subfile.stuff()         # Do stuff with global var
print settings.myList[0] # Check the result

Таким образом, вы достигаете своей цели, избегая инициализации глобальных переменных более одного раза.

Ответ 2

Смотрите документ Python о совместном использовании глобальных переменных между модулями:

Канонический способ обмена информацией между модулями в рамках одной программы - создать специальный модуль (часто называемый config или cfg).

config.py:

x = 0   # Default value of the 'x' configuration setting

Импортируйте модуль конфигурации во все модули вашего приложения; модуль становится доступным как глобальное имя.

main.py:

import config
print config.x

или же

from config import x
print x

Это также позволит вам динамически устанавливать такую переменную:

import config
config.x = my_function

В общем случае не используйте импорт по модулю *. Это приводит к загромождению пространства имен импортеров и затрудняет для линтеров обнаружение неопределенных имен.

Ответ 3

Вы можете думать, что глобальные переменные Python являются "модульными" переменными - и поэтому они гораздо полезнее традиционных "глобальных переменных" из C.

Глобальная переменная фактически определена в модуле __dict__ и может быть доступна извне этого модуля в качестве атрибута модуля.

Итак, в вашем примере:

# ../myproject/main.py

# Define global myList
# global myList  - there is no "global" declaration at module level. Just inside
# function and methods
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

и

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
     # You have to make the module main available for the 
     # code here.
     # Placing the import inside the function body will
     # usually avoid import cycles - 
     # unless you happen to call this function from 
     # either main or subfile body (i.e. not from inside a function or method)
     import main
     main.mylist.append("hey")

Ответ 4

Использование from your_file import * должно устранить ваши проблемы. Он определяет все, чтобы он был глобально доступен (за исключением локальных переменных в импорте, конечно).

например:

##test.py:

from pytest import *

print hello_world

и

##pytest.py

hello_world="hello world!"

Ответ 5

Ответ на Hai Vu отлично работает, только один комментарий:

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

# settings.py
def init(arg):
    global myList
    myList = []
    mylist.append(arg)


# subfile.py
import settings

def print():
    settings.myList[0]


# main.py
import settings
settings.init("1st")     # global init before used in other imported modules
                         # Or else they will be undefined

import subfile    
subfile.print()          # global usage

Ответ 6

Ваша вторая попытка будет работать отлично и на самом деле является действительно хорошим способом обработки имен переменных, которые вы хотите получить глобально. Но у вас есть ошибка имени в последней строке. Вот как это должно быть:

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

См. последнюю строку? myList - это attr файла globfile, а не подфайла. Это будет работать так, как вы хотите.

Mike