在函数中初始化全局变量时更改其类型
我有一个 __main__
函数,在里面我初始化了很多变量,后面会用到。有个问题是,我在外部作用域临时把一个变量设为 None,然后给它赋值为 SomeClass 的一个对象,但由于作用域的规则,我无法在外部访问这个对象的内容。因为 SomeClass 的构造函数需要传入一个参数,所以我不能直接把 myObject 声明为 foo.bar.SomeClass
。那么我该怎么做才能访问 foo.bar.SomeClass 中的属性呢?
代码看起来是这样的:
myObject = None
def setUp():
... lots of initialization ...
myObject = foo.bar.SomeClass(init_variable)
if __name__ == "__main__":
setUp()
myObject.member1 #throws AttributeError: 'NoneType' object has no attribute member1
3 个回答
0
如果你的 SomeClass
需要在脚本执行时传入一些信息,最简单的方法就是把你需要的信息作为参数传进去,这样就能创建这个类的实例了。可能看起来像这样:
def initialize(args):
... lots of initialization ...
myObject = foo.bar.SomeClass(args[0])
if __name__ == "__main__":
initialize(sys.argv)
另一种方法是使用 global
关键字,把 myObject 实例设为全局变量,然后再调用 initialize()
。
2
你不一定要这样做——使用全局变量在大多数情况下被认为是不好的做法。你可以直接返回你想要的数据:
def initialize():
... lots of initialization ...
return foo.bar.SomeClass(init_variable)
if __name__ == "__main__":
myObject = initialize()
myObject.member1 # works
补充说明:
如果你需要初始化多个值,或者发现自己在很多顶层函数之间使用了太多全局变量来共享状态,那么是时候使用一个 class
(类)了。
class MyProgram(object):
def __init__(self):
# ... lots of initialization ...
self.myObject = foo.bar.SomeClass(init_variable)
def usage(self):
self.myObject.member1
if __name__ == "__main__":
m = MyProgram()
m.usage()
2
假设这里的 setup()
是指 initialize()
,问题在于 initialize()
里的变量 myObject
是一个局部变量,它把全局的 myObject
给隐藏了。当 initialize()
执行完毕后,这个局部变量就不再可用了。
如果你想更新全局的 myObject
变量,需要这样修改 initialize()
:
def initialize():
global myObject
... lots of initialization ...
myObject = foo.bar.SomeClass(init_variable)
添加 global
这个声明的意思是,你在更新的是全局的 myObject
,而不是一个局部的变量。