我遇到过这样一种情况:在3.3之前的Python上,unicode子类化会导致不推荐警告和python3.3错误:
# prove that unicode.__init__ accepts parameters
s = unicode('foo')
s.__init__('foo')
unicode.__init__(s, 'foo')
class unicode2(unicode):
def __init__(self, other):
super(unicode2, self).__init__(other)
s = unicode2('foo')
class unicode3(unicode):
def __init__(self, other):
unicode.__init__(self, other)
s = unicode3('foo')
奇怪的是,警告/错误并没有出现在前三行,而是出现在第8行和第14行。下面是Python2.7的输出。在
^{pr2}$为了说明这个问题,代码被简化了。在实际的应用程序中,我将执行的操作不仅仅是调用super __init__
。在
从前三行来看,unicode类实现了__init__
,并且该方法至少接受一个参数。但是,如果我想从子类中调用该方法,无论是否调用super()
,我似乎都无法这样做。在
为什么在unicode实例上调用unicode.__init__
而不是unicode子类?如果unicode类的子类化,作者应该怎么做?在
我怀疑这个问题是因为
unicode
是不可变的。在创建
unicode
实例后,无法对其进行修改。因此,任何初始化逻辑都将在__new__
方法中(调用该方法来创建实例),而不是__init__
(只有在实例存在之后才调用)。在不可变类型的子类没有相同的严格要求,因此如果您愿意,可以在
unicode2.__init__
中执行操作,但是调用unicode.__init__
是不必要的(而且可能不会执行您认为它会做的事情)。在更好的解决方案可能是使用您自己的
__new__
方法执行自定义逻辑:如果您愿意,您也可以使类不可变,方法是给它一个总是引发异常的
__setattr__
方法(您可能还想给类一个__slots__
属性,通过省略每个实例__dict__
来节省内存)。在相关问题 更多 >
编程相关推荐