Python Jython全局变量usag

2024-10-01 07:27:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我对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'}

除了简单得多,它现在工作得非常完美。在


Tags: 代码selfeventdefglobalabcchosenchoice
3条回答

您可以重新创建相同的错误:

global chosen2 #you're not creating chosen2, just saying you're about to create it, and when you do - it should be a global variable
chosen2[2]=2 #chosen2 has yet to be defined so how can you set anything?

您试图设置尚未定义的对象two的属性,首先必须说明您希望它是列表还是字典(或其他)。在

^{pr2}$

如前所述,我不认为您希望这是全局的(因为您希望能够创建具有不同chosen2值的类实例!

这里不需要使用global。在您的示例中,chosen和{}是类属性。而不是:

global chosen
chosen = self.choice

你只要写下:

^{pr2}$

在类之前定义chosen2时,实际上是在global所指的范围内定义它。当您在类范围内定义它时,它是一个由所有实例共享的类属性。在

更新:如前所述,直接赋值给class属性不是您想要的,因为它将在实例上创建一个新属性,该属性将在类上屏蔽它。但在您的Listener2示例中,这是可以的:

def actionPerformed(self, event):
    self.chosen[self.choice] = event

在这里,您没有重写.chosen,而是将一个项添加到它所引用的字典中,这样类将为每个侦听器保存最新事件的记录。在

global都没有你认为的那样。在这两种情况下,chosen和{}都是变量,而不是全局变量。在

但是当您将chosen声明为全局变量并分配给它时,python很高兴地创建了一个全局变量(与Listener1.chosen分开)并存储了您的值。在

但是对于chosen2您没有给它赋值;您试图将它当作dict来处理,但是您没有通过赋值创建变量,因此失败了。在

您希望使用self.chosen2;作为一个类变量,Listener2的所有实例都可以使用它。您也可以使用Listener2.chosen2。对于chosen,可以使用Listener1.chosen来引用它。可以完全删除global关键字。在

在任何情况下,将变量声明为global并不意味着超出了我当前的作用域。它的意思是在模块范围,所以总是在函数、类和方法定义之外。在

相关问题 更多 >