2010-06-23 86 views
6

我正在處理一些爲我自動生成的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

給出了一個錯誤的噓聲沒找到foo中。但酒吧進口都foo & boo。不應該自動提供噓?

有沒有辦法做到這一點?如上所述boo.py是我自動生成的&我想避免添加導入foo到boo.py

謝謝。

回答

14

但欄導入這兩種富&噓聲。 不應該自動 可用噓?

沒有它不應該:import,要綁定一個名字任何其他方式,結合在一個單一的,特定範圍的名字,而不是「在所有範圍內,你可以永遠不可能想它。」

有沒有辦法做到這一點?至於說 boo.py爲 我&自動生成我希望避免增加進口富 到boo.py

有一個非常糟糕的黑客 - 我不想忍受它(I」 d倒不如將我的精力投入到獲得完全破壞的代碼生成器中,使得boo.py得到修復 - 如果它具有如此巨大的缺陷以至於缺少必要的重要輸入,那麼它還有什麼其他的恐懼?!),但是,嘿,它不是我的殯葬... ;-)

bar.py開始...:

import foo 
import boo 
import __builtin__ 
__builtin__.foo = foo 

您所做標識符foo這樣一個「假的,人造的內置名」(唯一的一種名稱的那可以從每一個範圍,除非通過在名稱 其他介入綁定陰影參考模塊foo更近的示波器)。

不是推薦的程序,只是代碼生成器中可怕的,明顯的bug的臨時解決方法,它生成boo.py得到修正的錯誤所以你可以儘快退休這個黑客! OK。

+0

好的。我會要求這些人手動添加「import foo」到所有這些py文件。稍後我會修復這個.py生成工具。 謝謝。 – sambha 2010-06-24 00:17:44

+1

@AlexMartelli我碰到了這個黑客攻擊,爲了我的目的,這已經足夠了。但是我仍然對把名字放入'__builtin__'中的所有含義感到困惑。除了名稱衝突的明顯問題外,還有其他一些值得注意的陷阱嗎? – LavaScornedOven 2013-11-26 06:33:38

3

不需要。如果您想在boo中使用foo,則需要將其導入boo。在bar中的import foo僅在bar模塊中提供foo

一般來說,Python中的import語句有點像變量定義。其實你可以把它想的是:精神與

boo = __import__('boo') 

更換

import boo 

__import__是Python解釋器的內置功能,要麼導入一個模塊,或者查找現有的引用模塊,如果它已被導入,並返回該參考)

無論自動生成boo.py是做錯了。它應該在該文件的某個位置添加import foo。您可以通過在bar.py這樣繞過它:

import foo 
import boo 
boo.foo = foo 

,但你真的不應該那麼做。 (我重複一下亞歷克斯·馬爾泰利說過這種事情是一個巨大的黑客)

+0

OK。謝謝。我會等待更多的時間讓別人加入。如果任何人有一些竅門。否則 - 我必須做我該做的事情! – sambha 2010-06-23 22:48:30

+0

K.我們將手動將import foo添加到這些py文件中,以便稍後修復此工具。我有時討厭python的這種「嚴格性」,但隨着時間的推移,我明白這一點 - 它通常是「正確的方式」。謝謝。 – sambha 2010-06-24 00:23:12

4

你必須在噓聲

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" 
導入FOO
+1

循環進口表示設計錯誤。 – 2010-06-23 23:58:47

+0

,並且當代碼太緊時,解決問題會很痛苦...重構是唯一的解決方案;)這就是爲什麼我愛蟒蛇:) – 2011-07-28 14:27:20

+1

@MikeGraham我沒有在這裏看到一個循環導入... – drevicko 2016-06-21 12:35:13

4

每個模塊都有自己的名稱空間。因此,爲了讓boo.py看到來自外部模塊的東西,boo.py必須自己導入它。

有可能編寫一種語言,其中名稱空間按照您期望的方式堆疊:這稱爲動態範圍界定。像原始lisp,早期版本的perl,postscript等一些語言確實使用(或支持)動態範圍。

大多數語言使用詞法作用域代替。事實證明,這對於語言的工作來說是一個更好的方式:這樣一個模塊就可以根據自己的代碼推斷它將如何工作,而無需擔心如何調用它。

請參閱本文的其他詳細信息:http://en.wikipedia.org/wiki/Scope_%28programming%29