扩展Python类时更新静态变量

扩展Python类时更新静态变量,python,dictionary,extending-classes,Python,Dictionary,Extending Classes,我正在编写一个库的扩展,我想用基类中函数指针的字典注册我的新函数。我的理解是,字典是静态的,应该是可更新的,因为它位于类中的最高作用域。但是,当我尝试在扩展类中使用新函数update()字典时,它告诉我它是未定义的。以下示例再现了该错误: def somefunction1(v): 返回v 定义功能2(v): 返回v 类SomeClass(对象): dictionary={'a':somefunction1} 类SomeExtensionClass(SomeClass): update({'b'

我正在编写一个库的扩展,我想用基类中函数指针的字典注册我的新函数。我的理解是,字典是静态的,应该是可更新的,因为它位于类中的最高作用域。但是,当我尝试在扩展类中使用新函数
update()
字典时,它告诉我它是未定义的。以下示例再现了该错误:

def somefunction1(v):
返回v
定义功能2(v):
返回v
类SomeClass(对象):
dictionary={'a':somefunction1}
类SomeExtensionClass(SomeClass):
update({'b':somefunction2})
运行它会产生以下错误

 9 
 10 class SomeExtensionClass(SomeClass):
 ---> 11         dictionary.update({'b':somefunction2})

NameError: name 'dictionary' is not defined
既然我不能(合理地)修改原始的
SomeClass
,有什么办法可以解决这个问题吗


编辑:所需的结果是
SomeExtensionClass
将具有
字典={'a':somefunction1,'b':somefunction2}

如果要修改
SomeClass.dictionary
,只需将其称为
SomeClass.dictionary

SomeClass.dictionary.update(whatever)
类中的变量查找
语句不会查看超类的属性

如果您想要一个新词典,因此
SomeExtensionClass.dictionary
不同于
SomeClass.dictionary
,您需要复制原始词典并更新副本:

class SomeExtensionClass(SomeClass):
    dictionary = SomeClass.dictionary.copy()
    dictionary.update(whatever)

有两种合理的方法可以为SomeExtensionClass提供更新的字典:

  • 通过参考
    SomeClass.dictionary
    更新原始词典
  • 为派生类定义第二个
    字典
    变量
  • 第二步可以这样做:

    class SomeExtensionClass(SomeClass):
        dictionary = dict(SomeClass.dictionary, b=somefunction2)
    
    def foo(self):
        a = self.dictionary['a']()
    
    你应该选择哪一个取决于谁使用这本词典以及使用什么。如果SomeClass方法使用如下变量:

    class SomeExtensionClass(SomeClass):
        dictionary = dict(SomeClass.dictionary, b=somefunction2)
    
    def foo(self):
        a = self.dictionary['a']()
    
    该方法将对SomeExtensionClass对象使用SomeExtensionClass字典。如果OTOH有:

    def foo(self):
        a = SomeClass.dictionary['a']()
    

    它将始终使用SomeClass中定义的字典。

    即使您可以执行
    dictionary.update({'b':somefunction2})
    ,您也将修改
    SomeClass
    。具体来说,
    SomeClass.dictionary
    现在将有一个
    'b'
    条目。这就是你想要的吗?是的。我更新了原来的问题,以反映这一点。“你不能在类范围内编写一般性语句”-不清楚这是什么意思。什么是“一般性声明”?您可以在类范围内编写大多数类型的语句。@otus
    class SomeExtensionClass(SomeClass):dictionary=dict(SomeClass.dictionary,b=somefunction2)def prints(self):print(dictionary)a=SomeExtensionClass()a.prints()
    提供了一个
    名称错误:未定义全局名称“dictionary”。有什么想法吗?@Higany,在引用类变量时,您需要通过类(
    SomeExtensionClass.dictionary
    )或实例(
    self.dictionary
    )来引用。有关差异,请参见例如。在您的
    prints
    示例中,您可能需要
    self.dictionary
    。这还将更新基类字典。这似乎是不受欢迎的行为。@ebar:这是OP说他想要的行为。可能有一个很好的理由;我们不完全知道发生了什么。看起来我误解了这个问题。我删除了我的答案,因为没有副本,它基本上与此相同。@user2357112显然我也不知道。是否可以创建
    SomeExtensionClass
    字典?Otus的方法给了我一个NameError。我正在更新原始问题。抱歉。@Higany:看来otus的评论应该已经澄清了这个问题。为变量查找检查类作用域的唯一情况是直接在类作用域中编写的语句。在方法中,必须使用属性引用,如
    self.dictionary
    SomeExtensionClass.dictionary