我对python全局变量的理解以及它们的正确用法有一个问题。第一位代码工作正常,第二位抛出异常“NameError:global name‘choosed’is not defined”。我肯定我错过了一些简单的东西,但我看不出是什么。在
我想将一个侦听器与许多事件生成器中的每一个关联起来,然后使用getChoices方法获取每个生成器所做选择的字典。在
#Working code
class Listener1():
chosen = "0"
def __init__(self, choice):
self.choice = choice
def actionPerformed(self, event):
global chosen
chosen = self.choice
@staticmethod
def getChoices():
return chosen
e1 = Listener1('evt1')
e1.actionPerformed('abc')
print Listener1.getChoices()
失败代码
^{pr2}$脚注:
如果类的第一行引用
由于下面的答案,代码重写为:
class Listener3():
chosen3 = {}
def __init__(self, choice):
self.choice = choice
if choice is not None:
self.chosen3[self.choice] = 'unset'
def actionPerformed(self, event):
val = event
self.chosen3[self.choice] = val
def getChoices(self):
return self.chosen3
e1 = Listener3('evt1')
e1.actionPerformed('abc')
e2 = Listener3('evt2')
e2.actionPerformed('def')
e3 = Listener3('evt3')
print Listener3(None).getChoices()
{'evt1': 'abc', 'evt2': 'def', 'evt3':'unset'}
除了简单得多,它现在工作得非常完美。在
您可以重新创建相同的错误:
您试图设置尚未定义的对象
^{pr2}$two
的属性,首先必须说明您希望它是列表还是字典(或其他)。在如前所述,我不认为您希望这是全局的(因为您希望能够创建具有不同chosen2值的类实例!
这里不需要使用}是类属性。而不是:
global
。在您的示例中,chosen
和{你只要写下:
^{pr2}$在类之前定义
chosen2
时,实际上是在global
所指的范围内定义它。当您在类范围内定义它时,它是一个由所有实例共享的类属性。在更新:如前所述,直接赋值给class属性不是您想要的,因为它将在实例上创建一个新属性,该属性将在类上屏蔽它。但在您的
Listener2
示例中,这是可以的:在这里,您没有重写
.chosen
,而是将一个项添加到它所引用的字典中,这样类将为每个侦听器保存最新事件的记录。在global
都没有你认为的那样。在这两种情况下,chosen
和{但是当您将
chosen
声明为全局变量并分配给它时,python很高兴地创建了一个全局变量(与Listener1.chosen
分开)并存储了您的值。在但是对于
chosen2
您没有给它赋值;您试图将它当作dict来处理,但是您没有通过赋值创建变量,因此失败了。在您希望使用
self.chosen2
;作为一个类变量,Listener2
的所有实例都可以使用它。您也可以使用Listener2.chosen2
。对于chosen
,可以使用Listener1.chosen
来引用它。可以完全删除global
关键字。在在任何情况下,将变量声明为
global
并不意味着超出了我当前的作用域。它的意思是在模块范围,所以总是在函数、类和方法定义之外。在相关问题 更多 >
编程相关推荐