В простейшем случае мы записываем коды в один файл Python (имя файла заканчивается на .py). Запускаем, все работает как положено, и мы довольны. Однако все может немного усложниться, когда вам придется разделить код на несколько файлов Python, обычно для упрощения управления кодом и читаемости. В этой статье я расскажу вам о некоторых типичных ошибках, на которые я попал, и надеюсь, что вы не сделаете тех же ошибок, что и я.

В Python каждый файл Python фактически имеет определенный термин под названием «Модуль», и когда вы используете знаменитый синтаксис import, вы устанавливаете соединение между несколькими различными модулями Python для решения сложной задачи в вашем контексте. Здесь я собираюсь проиллюстрировать следующие темы:

  1. У каждого файла своя глобальная переменная
  2. Функция всегда запоминает, где она была создана
  3. Python - это «передача по ссылке»
  4. Использование отдельного файла для хранения ГЛОБАЛЬНОЙ переменной в нескольких файлах Python

Если вы хотите узнать о них побольше, продолжайте читать!

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

Когда вы создаете переменную (не внутри функции) в файле Python, вы подключаете эту переменную к пространству имен текущего модуля. Каждая команда в этом файле Python может получить доступ, прочитать и изменить значение переменной, то есть она становится глобальной переменной. Вы также можете явно сделать переменную, определенную в функциях глобально, объявив itglobal.

Однако глобальные переменные не используются в разных файлах Python. Чтобы проиллюстрировать это, давайте посмотрим на следующий пример:

Логика очень ясна, я определил функцию в sub_module.py и пытаюсь вызвать ее в main.py файле. Кажется, я определил переменную num=5 в файле main.py, но оказалось, что функция не может получить к ней доступ, причина в том, что sub_module.py не может получить доступ к глобальной переменной в других модулях Python, поэтому num=5 невидим для программы. Как это исправить? Просто определите num в нужном файле.

Функция Python всегда запоминает место создания

Я не уверен, что вы когда-нибудь запутались в приведенном выше примере? Я так и сделал, когда впервые посмотрел на этот пример, потому что я явно импортировал test_func1 из sub_module.py в main.py, естественно думать, что функция уже была в текущей области, не так ли?

Но функция Python всегда знает, где она была создана. Хотя кажется, что test_func1 находится в main.py, он по-прежнему принадлежит sub_module.py, когда запускается, потому что именно здесь он был создан. А теперь еще несколько полезных практических советов:

Не забудьте также импортировать необходимые пакеты в подмодуль!

В приведенном выше примере, поскольку мы забыли импортировать пакет NumPy в sub_module.py, хотя мы импортировали его в main.py, он по-прежнему недоступен для test_func1. А теперь исправим:

Передача по ссылке против передачи по значению

Первый пример работает, но выглядит странно, не правда ли? Обычно мы просто определяем функцию и класс в подмодуле вместо того, чтобы помещать одну переменную num=5. Обычный способ решить эту проблему - фактически добавить num в качестве аргумента в test_func1, а также передать num=5 функции при ее вызове в main.py файле.

Теперь вопрос в том, как сделать так, чтобы sub_module.py узнал, где находится num? Это потому, что Python всегда передает по ссылке, а не по значению. Чтобы проиллюстрировать это, давайте посмотрим, что на самом деле происходит, когда вы вызываете функцию:

Когда вы вводите num=5 в main.py, вы в основном создаете PyObject с целочисленным типом, который находится в части физической памяти, и вы используете имя num, чтобы указать на этот кусок физической памяти. Теперь, поскольку Python всегда передает по ссылке, вы можете подумать, что test_func1 будет знать, на что указывает имя num. В результате он получит доступ к value 5, поскольку он буквально знает, где находится это значение.

Могу ли я иметь общую глобальную переменную для разных файлов?

Как мы уже говорили, глобальная переменная уникальна для своего собственного модуля. Но иногда нам действительно нужно иметь ГЛОБАЛЬНУЮ переменную, к которой можно получить доступ и изменить каждый файл Python в каталоге. Канонический способ добиться этого - создать другой файл с вашими ГЛОБАЛЬНЫМИ переменными.

Я специально усложнил этот пример; здесь у нас есть gloabl_.py файл Python, содержащий num=10. Но в файле main.py я также создал num=5. Он может рассказать вам о различиях, даже если они оба были названы как num, но они относятся к разным областям. В main.py мы модифицируем эту ГЛОБАЛЬНУЮ переменную, добавляя 1, и это изменение также будет отражено в sub_module.py. Здесь я должен импортировать global_ в test_func2 функцию, потому что, если я помещу синтаксис импорта в начало, num он будет импортирован до выполнения lineglobal_.num += 1. Помните, что sub_module.py было выполнено в строке from sub_module import *, мы можем проверить это в следующем примере:

Как вы видели, теперь, несмотря на то, что глобальная переменная num увеличилась на 1, это не было отражено в sub_module.py, поскольку переменная, которую они импортировали, была получена до операции. При импорте Python автоматически сделает для вас копию, так что старый global_.num и новый global_.num будут жить в совершенно другой физической памяти.

Заключение

Вот несколько рекомендаций по работе с несколькими файлами Python:

  1. Передайте переменную в качестве аргумента, поскольку Python «передает по ссылке», что гарантирует, что ваш подмодуль может получить доступ к переданной вами переменной.
  2. Не забудьте также импортировать необходимый пакет в подмодуль, так как функция всегда запоминает, где он был создан.
  3. Использование отдельного файла для хранения переменной GLOBAL в модулях Python, но имейте в виду, что при импорте переменной GLOBAL будет сделана копия исходной, поэтому всегда проверяйте, ссылаетесь ли вы на правильную переменную в своей программе. .

Вот и все! Надеюсь, эта статья окажется для вас интересной и полезной, спасибо за внимание! Если вам понравилась эта статья, подпишитесь на меня в среднем, большое спасибо за вашу поддержку. Подключите меня к моему Twitter или LinkedIn, а также дайте мне знать, если у вас есть какие-либо вопросы или какие уроки вы хотели бы видеть в будущем!