我有一個應用程序在Postgres上運行& Mysql。每個程序檢查以確定數據庫,然後以db_util或db_util的形式導入postgres_db作爲db_util或mysql_dt。當主引用db_util中的代碼都運行良好時,但如果導入了類,則未定義對db_util的引用。Python導入爲全局名稱未定義
我創建了以下類和主要測試問題,並發現另一個有趣的副作用。 B類& C參考不同導入情況下的ClassA。 B & C是相同的,除了B在主要和C是進口。
ClassX.py
class ClassA(object):
def print_a(self):
print "this is class a"
class ClassC(object):
def ref_a(self):
print 'from C ref a ==>',
xa=ClassA()
xa.print_a()
def ref_ca(self):
print 'from C ref ca ==>',
xa=ca()
xa.print_a()
test_scope.py
from classes.ClassX import ClassA
from classes.ClassX import ClassA as ca
from classes.ClassX import ClassC as cb
class ClassB(object):
def ref_a(self):
print 'from B ref a ==>',
xa=ClassA()
xa.print_a()
def ref_ca(self):
print 'from B ref ca ==>',
xa=ca()
xa.print_a()
print 'globals:',dir()
print 'modules','ca:',ca,'cb:',cb,'CA:',ClassA
print ''
print 'from main'
xb=ClassB()
xb.ref_a()
xb.ref_ca()
print ''
print 'from imports'
xbs=cb()
xbs.ref_a()
xbs.ref_ca()
而且結果:
globals: ['ClassA', 'ClassB', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'ca', 'cb']
modules ca: <class 'classes.ClassX.ClassA'> cb: <class 'classes.ClassX.ClassC'> CA: <class 'classes.ClassX.ClassA'>
from main
from B ref a ==> this is class a
from B ref ca ==> this is class a
from imports
from C ref a ==> this is class a
from C ref ca ==>
Traceback (most recent call last):
File "test_scope.py", line 32, in <module>
xbs.ref_ca()
File "R:\python\test_scripts\scope\classes\ClassX.py", line 13, in ref_ca
xa=ca()
NameError: global name 'ca' is not defined
Press any key to continue . . .
從我的測試中,我看到的對象CA(進口AS)是不可用於ClassC,但是,ClassA模塊可用(導入時不帶)。
- 爲什麼導入和導入之間的區別是行爲?我不清楚爲什麼主要全球供應商不能上課。
- 什麼是動態確定適當的db_util模塊導入並讓其他導入的類可訪問的好方法?
更新: 閱讀命名空間的另一個職務後:「Visibility of global variables from imported modules」,據我所知,在我的例子上述原因ClassA的是提供給ClassC是,& C是在同一個導入文件,因此相同的命名空間。
所以剩下的問題是一個設計問題:
,如果我有這樣的代碼:
if db == 'MySQL':
from mysql_db import db_util
elif db == 'Postgres'
from postgres_db import db_util
什麼是一個好方法,使db_util適用於所有進口的模塊?
UPDATE:
從Blckknght的效應初探,我加入了代碼
cb.ca =ca
到scope_test腳本。這需要的類呼叫xa = ca()被更改爲xa = self.ca()。我也認爲,雖然Python允許將對象添加到類外,但這不是一個好的設計方法,它將使調試成爲一場噩夢。
但是,因爲我認爲模塊和類應該是獨立的或專門聲明它們的依賴關係,所以我將使用上面的代碼示例來實現類。
突圍ClassA和ClassC分離模塊,並在ClassC的頂部,類定義之前,做進口
from ClassA import ClassA
from ClassA import ClassA as ca
class ClassB(object):
,並在我的實際情況,在那裏我需要將db_util模塊導入數模塊
ci.py #NEW模塊在每個模塊中,選擇適當的類分貝
if db == 'MySQL':
from mysql_db import db_util
elif db == 'Postgres'
from postgres_db import db_util
需要的db_util類
import ci
db_util=ci.db_util #add db_util to module globals
class Module(object):
這樣做的一個問題是它需要每個模塊使用db_util來導入它,但它確實使依賴性已知。
我會關閉這個問題,並希望感謝Blckknght和Armin Rigo的回覆,這些回覆有助於爲我解釋這個問題。我會很感激任何與設計有關的反饋。
我在導入後立即在上面的test_scope.py腳本中添加了'cb.ca = ca',認爲這會將ca添加到cb名稱空間。我仍然沒有定義全局,當我從ClassC打印全局變量時,它會打印全局變量:['self'] - 沒有對ca的引用,錯誤仍然存在。我錯過了什麼? – cswaim 2013-05-02 22:30:58
我錯過了ca必須被引用爲self.ca,因爲ca現在在類中定義。 – cswaim 2013-05-03 17:47:54