Python истинные глобальные переменные (python 3.7.0) - PullRequest
1 голос
/ 18 февраля 2020

Я знаю, что вы можете использовать ключевое слово global. Но это не ... глобально. Это просто способ ссылки на другую переменную вне этой функции. Если у вас есть одна переменная, на которую вы хотите сослаться, я думаю, это не так уж и сложно (хотя все еще хлопотно). Но что, если у вас много переменных, которые вы хотите перемещать по функциям? Нужно ли объявлять эти 2, 3 или 10 переменных каждый раз в каждой функции, которые имеют глобальную область видимости? Разве нет способа объявить [1] переменную (где-то или как-то), чтобы она была действительно глобальной?

В идеале я хотел бы иметь один файл main.py с моим основной код и один файл common.py со всеми моими глобальными переменными (объявленными / инициализированными [1]) и с from common import * я мог бы использовать каждую переменную, объявленную в common.py .

Прошу прощения, если это дубликат. Я искал вокруг, но я не могу что-то найти. Может быть, вы могли бы сделать это с классами (?), Но я стараюсь избегать их использования для этой конкретной программы (но если нет другого способа, я возьму это)

РЕДАКТИРОВАТЬ: Добавление кода чтобы показать пример двух неработающих файлов:

файл main.py

from common import *

def func1():
    x=2
    print('func1', x)

def func2():
    print('fuc2',x)

print('a',x)
func1()
func2()

файл common.py

x=3

это печатает:

a 3
func1 2
fuc2 3

, но должно печатать:

a 3
func1 2
fuc2 2

, потому что func2, даже если он вызывается после func1 (где x назначено значение), видит x как 3 Это означает, что fuc1 фактически не использовал «глобальную» переменную x, а локальную переменную x, отличную от «глобальной». Поправьте меня, если я ошибаюсь


[1] Я знаю, что в python вы на самом деле не объявляете переменные, вы просто инициализируете их, но вы получаете мою точку зрения

1 Ответ

3 голосов
/ 18 февраля 2020

Технически, каждая переменная уровня модуля является глобальной, и вы можете связываться с ними из любого места. Простой пример, который вы, возможно, не осознали: sys:

import sys

myfile = open('path/to/file.txt', 'w')
sys.stdout = myfile

sys.stdout - глобальная переменная. Многие вещи в различных частях программы - включая части, к которым у вас нет прямого доступа, - используйте их, и вы заметите, что изменение здесь приведет к изменению поведения всей программы. Если что-нибудь и где-либо использует print(), оно будет выводиться в ваш файл вместо стандартного вывода.

Вы можете настроить это поведение, просто создав common исходный файл, который доступен для всего вашего проекта:

common.py

var1 = 3
var2 = "Hello, World!"

sourcefile1.py

from . import common

print(common.var2)
# "Hello, World!"

common.newVar = [3, 6, 8]

fldr/sourcefile2.py

from .. import common

print(common.var2)
# "Hello, World!"
print(common.newVar)
# [3, 6, 8]

Как видите, вы даже можете назначить новые свойства, которых не было вообще (common.newVar).

Однако, может быть, лучше просто поместить dict в common и сохранить в нем свои различные глобальные значения - нажатие нового ключа к dict проще в обслуживании, чем операция. добавление нового атрибута в модуль.


Если вы используете этот метод, вы захотите с осторожностью делать from .common import *. Это исключает возможность изменения ваших глобальных переменных из-за пространств имен - когда вы присваиваете новое значение, вы изменяете только свое локальное пространство имен.

Как правило, по этой причине вы не должны делать import *, но это является частным симптомом этого.

...