Python3 глобальный обзор в разных модулях - PullRequest
1 голос
/ 22 февраля 2020

Я хотел бы уточнить, как распределены глобальные переменные из разных модулей?

Мне не удалось найти соответствующую документацию по этому вопросу, поэтому я полагаюсь на наблюдения, но я хотел бы получить более глубокое понимание, если мои выводы являются простым совпадением реализации или я могу им доверять?

Тестовый случай:

module_1.py:

global_var1 = 'm1_v1'
global_var2 = 'm1_v2'

def f():
 print('f: {}'.format(global_var1))
 print('f: {}'.format(global_var2))

module_2.py:

import module_1

global_var1 = 'm2_v1'

def g():
 print('g: {}'.format(global_var1))
 print('g: {}'.format(global_var2))

module_1.f()

g()

$ python3 module_2.py

f: m1_v1
f: m1_v2
g: m2_v1
Traceback (most recent call last):
  File "module_2.py", line 11, in <module>
    g()
  File "module_2.py", line 7, in g
    print('g: {}'.format(global_var2))
NameError: name 'global_var2' is not defined

Вывод:

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

  1. модуль, в котором используется функция
  2. модуль, в котором определена функция (РЕДАКТИРОВАТЬ: это единственный ответ!)

Глобальные не удаляется из импортированных модулей.

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

Вопрос:

Я хотел бы видеть некоторая исчерпывающая документация по этому вопросу (которую я не смог найти ...).

Хотя тестирование это хорошо, я понятия не имею, если это странное совпадение, и этому поведению никогда нельзя доверять, или это ожидаемый способ?

Кроме того, что если функция как-то импортируется через 3-й модуль? что если функция является методом класса? Et c .et c.

Если вы не можете указать мне документацию, но вы знаете руководство "наверняка", мне тоже интересно.


Я не буду go подробно, почему и как я хочу это использовать, мне в первую очередь интересно лучше понять работу python. Однако, если вы знаете лучшее решение, учитывая имеющуюся информацию, мне также интересно это увидеть - оно НЕ будет принято в качестве ответа.


В случае, если есть разница между python2 и python3, мой основной интерес - python3, но также приятно иметь информацию о python2.

Ответы [ 2 ]

2 голосов
/ 22 февраля 2020

Каждый модуль имеет свою глобальную область видимости. Давайте посмотрим на второй модуль:

import module_1

global_var1 = 'm2_v1'

def g():
 print('g: {}'.format(global_var1))
 print('g: {}'.format(global_var2))

module_1.f()

g()

Поскольку global_var1 и global_var2 не являются локальными переменными, они ищутся в глобальной области видимости. Поскольку module_2.global_var2 не определено, вы получаете NameError.

. Вам нужно будет либо создать module_2.global_var2 с чем-то вроде from module_1 import global_var2, либо изменить определение g на

def g():
    print('g: {}'.format(global_var1))
    print('g: {}'.format(module_1.global_var2))

import module_1 добавляет только одно имя к глобальной области действия module_2, то есть module_1, которое относится к объекту module, созданному оператором import. from module_1 import global_var2 также добавляет только одно имя, global_var2, которое инициализируется к значению module1.global_var2 (хотя с побочным эффектом создания нового модуля). В этом случае module1.global_var2 и module2.globar_var2 - это два различных объекта, а не два имени для одного и того же объекта.

1 голос
/ 22 февраля 2020

TLDR: Python использует лексический / stati c scoping с Python 2.1, включая Python 3. (См. разрешение имен и PEP 227 )


Лексическая область видимости означает, что функции имеют доступ только к окружающим областям действия , в которых они определены , вплоть до глобального пространства имен их модуля. Только builtins видны во всех модулях. Глобальное пространство имен модулей не используется совместно, и импорт или вызов функции в другом модуле не дает ему доступа к этому пространству имен.

Некоторые особенности, на которые следует обратить внимание:

  • Local / Области действия функции определяются при разборе функции. Имена бывают локальные, замыкания / нелокальные или глобальные.
  • Глобальные / модульные области видимости являются изменяемыми. Имена могут быть добавлены, удалены или изменены в любое время.
  • Классы представляют краткосрочные области действия, которые не видны для функций или других классов, определенных внутри них.
...