【发布时间】:2013-03-14 06:25:07
【问题描述】:
我试图将我的代码分布在不同的文件中以提高可读性,但我遇到了在导入文件中引用未定义的全局名称的麻烦。有没有比在调用时故意将所有必要的值传递给函数更好的解决方案?
我的代码目前是这样的:
#foo.py
import bar
def main():
a = 1
b = bar.Bar()
while True:
a += 1
b.incr()
print a
print b.c
if __name__ == '__main__':
main()
#END foo.py
-
#bar.py
class Bar:
def __init__(self):
self.c = 0
def incr(self):
self.c += a
#END bar.py
它给了我 NameError: global name 'a' is not defined。我是否需要像这样重写 main():
def main():
b = new bar.Bar()
while True:
a += 1
b.incr(a)
print a
print b.c
然后像这样重写incr():
def incr(self,a):
c += a
或者有没有更好的方法?
为了记录,上面的代码被大量抽象了。实际代码涉及大量类和函数,它们传递多种类型的许多变量,包括一些大型字典。
提前致谢!
【问题讨论】:
-
由于全局变量通常不是一个好主意,在函数之间传递变量是更好的选择。
-
感谢@PurityLake 和 MartijnPieters - 关于性能,这不是问题吗?是否有一个很好的解决方案可以将大量变量从函数传递到函数?将它们全部放入字典或字典字典中,也许?
-
访问 locals 比访问 globals 更快,而且 globals 字典通常要大得多,使事情变得更糟。所以这可能不是问题;这可能是一种改进。无论如何,性能在这里不太可能是相关的。但如果这是一个问题,请将其作为
Bar实例上的对象属性。并使用__slots__而不是实例字典。或者将Bar移动到 Cython。或者…… -
对象的教科书用法是将数据与函数关联起来。如果您有一些函数定期使用/修改的长期数据,那么这就是对象的用途。如果您发现您需要一个对象中的一些数据经常存在于另一个对象中,那么您可能需要继承、组合或重新设计您的代码。
-
@yoel: 将
config字典传递给每个对象的__init__怎么样,所以main 可以更改config['gravity'] = 2,而Rock可以检查self.config['gravity']并找到新值?或者您可以将配置设置为类实例而不是字典,所以它是self.config.gravity。其中一个有问题吗?
标签: python python-2.7 global-variables