在函数中初始化全局变量时更改其类型

0 投票
3 回答
2818 浏览
提问于 2025-04-15 19:41

我有一个 __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,而不是一个局部的变量。

撰写回答