Объем “импорта” Python

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

foo.py:

def foo():
  print "foo"

boo.py:

def boo():
  foo.foo()    # <-- global name 'foo' not defined
  print "boo"

bar.py:

import foo
import boo
def bar():
  boo.boo()
  print "bar"

Выполнение:

python.exe bar.py

дает ошибку это boo не нашел foo. Но панель импортирует обоих foo & boo. Не был должен foo будьте автоматически доступны boo?

Существует ли способ сделать так? Как сказано boo.py автоматически сгенерирован для меня, и я не хочу добавлять нечто импорта к boo.py.

Спасибо.

8
задан Filipp W. 31 January 2019 в 06:55
поделиться

4 ответа

Но bar импортирует и foo, и boo. Разве foo не должно быть автоматически доступным для boo?

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

Есть ли способ сделать это? Как было сказано boo.py автоматически генерируется для меня, и я хочу избежать добавления import foo в boo.py

Есть один очень плохой хак - я бы не хотел жить с ним (я бы предпочел потратить свою энергию на то, чтобы исправить этот полностью сломанный генератор кода, который делает boo.py - если в нем есть такая огромная ошибка, как отсутствие критически важного необходимого импорта, то какие еще ужасы он может иметь в запасе?! ), но, эй, это не мои похороны...;-)

Пусть bar.py начнет...:

import foo
import boo
import __builtin__
__builtin__.foo = foo

Таким образом вы сделали идентификатор foo "фальшивым, искусственным встроенным именем" (единственный вид имени, который доступен из любой области видимости, если только его не затеняют другие промежуточные привязки имени в более близких областях), ссылающееся на модуль foo.

НЕ рекомендуемая процедура, просто временное обходное решение для ужасной, бросающейся в глаза ошибки в генераторе кода, который собирает boo.py. Исправьте эту ошибку, и вы сможете удалить этот хак как можно скорее!

15
ответ дан 5 December 2019 в 06:09
поделиться

вы должны импортировать foo в boo

boo.py

import foo

def boo():
  foo.foo()    # <-- global name 'foo' not defined
  print "boo"

bar.py

import boo

def bar():
  boo.boo()
  print "bar"
4
ответ дан 5 December 2019 в 06:09
поделиться

Нет. Если вы хотите, чтобы foo был доступен в boo , вам необходимо импортировать его в boo . import foo , который находится в bar , делает доступным только foo в модуле bar .

В общем, оператор import в Python похож на определение переменной. На самом деле вы можете думать об этом так: мысленно замените

import boo

на

boo = __import__('boo')

( __ import __ - встроенная функция интерпретатора Python, которая либо импортирует модуль, либо ищет ссылку на существующий модуль, если он уже импортирован и возвращает эту ссылку)

Все, что автоматически генерирует boo.py , делает это неправильно. Он должен добавить import foo где-нибудь в этот файл. Вы можете обойти это, сделав это в bar.py :

import foo
import boo
boo.foo = foo

, но на самом деле вам не нужно этого делать. (Я повторяю то, что сказал Алекс Мартелли о том, что такого рода вещи являются огромным взломом)

4
ответ дан 5 December 2019 в 06:09
поделиться

Каждый модуль имеет собственное пространство имен. Итак, чтобы boo.py увидел что-то из внешнего модуля, boo.py должен сам импортировать это.

Можно написать язык, на котором пространства имен располагаются так, как вы ожидаете: это называется динамической областью видимости. Некоторые языки, такие как исходный lisp, ранние версии perl, postscript и т. Д., Используют (или поддерживают) динамическую область видимости.

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

См. Дополнительную информацию в этой статье: http://en.wikipedia.org/wiki/Scope_%28programming%29

4
ответ дан 5 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: