在继承Python类时更新静态变量

0 投票
2 回答
685 浏览
提问于 2025-04-18 08:32

我正在为一个库写扩展,想把我的新函数注册到基类的一个函数指针字典里。我理解这个字典因为在类的最上层,所以是静态的,应该可以更新。但是,当我尝试用扩展类中的新函数去update()这个字典时,它告诉我这个函数是未定义的。下面这个简单的例子就能重现这个错误:

def somefunction1(v):
    return v

def somefunction2(v):
    return v

class SomeClass(object):
    dictionary = {'a':somefunction1}

class SomeExtensionClass(SomeClass):
    dictionary.update({'b':somefunction2})

运行这个代码会出现以下错误

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

NameError: name 'dictionary' is not defined

因为我不能(合理地)修改原来的SomeClass,有没有什么办法可以解决这个问题呢?

补充说明:我希望的结果是SomeExtensionClass会有dictionary={'a':somefunction1, 'b':somefunction2}

2 个回答

0

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

  1. 通过引用SomeClass.dictionary来更新原始字典。
  2. 为派生类定义一个第二个dictionary变量。

你可以这样做第二种方法:

class SomeExtensionClass(SomeClass):
    dictionary = dict(SomeClass.dictionary, b=somefunction2)

你选择哪种方法取决于谁在使用这个字典,以及他们用它来做什么。如果SomeClass中的某个方法这样使用变量:

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

那么这个方法会使用SomeExtensionClass的字典,专门针对SomeExtensionClass对象。如果相反,它这样做:

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

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

2

如果你想修改 SomeClass.dictionary,只需要直接用 SomeClass.dictionary 来引用它:

SomeClass.dictionary.update(whatever)

class 语句中查找变量时,不会去查找父类的属性。

如果你想要一个新的字典,让 SomeExtensionClass.dictionarySomeClass.dictionary 不一样,你需要先复制原来的字典,然后更新这个复制的字典:

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

撰写回答