回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我有一个在Postgres&Mysql上运行的应用程序。每个程序检查以确定数据库,然后将postgres_db作为db_util或mysql_dt作为db_util导入。当main中的代码引用db_util时,所有这些都可以正常工作,但如果导入了类,则不会定义对db_util的引用。</p>
<p>我创建了下面的类和main来测试这个问题,并发现了另一个有趣的副作用。B&C类参考不同进口情况下的A类。B&C是相同的,只是B在主控和C是进口的。</p>
<p>类别x.py</p>
<pre><code>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()
</code></pre>
<p>测试范围.py</p>
<pre><code>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()
</code></pre>
<p>结果是:</p>
<pre><code>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 . . .
</code></pre>
<p>从我的测试中,我看到对象ca(imported as)对ClassC不可用,但是模块ClassA可用(不带as导入)。</p>
<ol>
<li>为什么导入和导入作为行为的区别?我不清楚为什么主要的全球不提供类主要进口。</li>
<li>动态确定要导入的合适的db_util模块并让其他导入的类可以访问它的好方法是什么?</li>
</ol>
<p><strong>更新:</strong>
在阅读了另一篇关于名称空间的文章:“<em><a href="https://stackoverflow.com/questions/15959534/python-visibility-of-global-variables-from-imported-modules?rq=1">Visibility of global variables from imported modules</a></em>”之后,我理解在上面的示例中,classA对ClassC可用的原因是:A&C位于同一个导入的文件中,因此是同一个名称空间。</p>
<p>所以剩下的问题是一个设计问题:</p>
<p>如果我有这样的代码:</p>
<pre><code>if db == 'MySQL':
from mysql_db import db_util
elif db == 'Postgres'
from postgres_db import db_util
</code></pre>
<p>如何使db_util对所有导入的模块都可用?</p>
<p><strong>更新:</strong></p>
<p>根据Blckknght的回复,我添加了代码</p>
<pre><code>cb.ca =ca
</code></pre>
<p>作用域测试脚本。这要求将对<strong>xa=ca()</strong>的类调用更改为<strong>xa=self.ca()</strong>。我还认为,尽管Python允许从类外部向类添加对象,但这并不是一种好的设计方法,而且会使调试成为一场噩梦。</p>
<p>但是,由于我认为模块和类应该是独立的或者明确声明它们的依赖关系,所以我将使用上面的代码示例来实现这样的类。</p>
<p>将ClassA和ClassC分开以分离模块,在ClassC的顶部,在类定义之前,进行导入</p>
<pre><code>from ClassA import ClassA
from ClassA import ClassA as ca
class ClassB(object):
</code></pre>
<p>在我的实际情况中,我需要将db_util模块导入到几个模块中</p>
<p>ci.py#为适当的数据库选择类的新模块</p>
<pre><code>if db == 'MySQL':
from mysql_db import db_util
elif db == 'Postgres'
from postgres_db import db_util
</code></pre>
<p>在每个需要db_util类的模块中</p>
<pre><code>import ci
db_util=ci.db_util #add db_util to module globals
class Module(object):
</code></pre>
<p>这方面的一个问题是它需要每个模块使用db_util来导入它,但它确实会使依赖关系为人所知。</p>
<p>我将结束这一问题,并要感谢布莱克克特和阿米恩里戈他们的回答,帮助我澄清这个问题。我会感谢任何与设计相关的反馈。</p>