我有一个应用程序在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