Python "импорт" сфера - PullRequest
       20

Python "импорт" сфера

7 голосов
/ 24 июня 2010

Я имею дело с кодом 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 автоматически генерируется для меня, и я хочу не добавлять import foo в boo.py .

Спасибо.

Ответы [ 4 ]

15 голосов
/ 24 июня 2010

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

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

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

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

Есть bar.py начало ...:

import foo
import boo
import __builtin__
__builtin__.foo = foo

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

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

4 голосов
/ 24 июня 2010

вы должны импортировать 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 голосов
/ 24 июня 2010

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

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

В большинстве языков используется лексическая область видимости.Оказывается, это намного более приятный способ работы языков: таким образом, модуль может рассуждать о том, как он будет работать, основываясь на своем собственном коде, не беспокоясь о том, как он был вызван.дополнительные детали: http://en.wikipedia.org/wiki/Scope_%28programming%29

4 голосов
/ 24 июня 2010

Нет.Если вы хотите, чтобы 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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...