Python 如何(或为什么不)从子类调用unicode.\uuuu init\uuuu
我遇到过这样一种情况,子类化unicode会导致Python 3.3之前版本出现弃用警告,Python 3.3出现错误:Python 如何(或为什么不)从子类调用unicode.\uuuu init\uuuu,python,constructor,subclass,Python,Constructor,Subclass,我遇到过这样一种情况,子类化unicode会导致Python 3.3之前版本出现弃用警告,Python 3.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(unico
# 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的输出
> python -Wd .\init.py
.\init.py:8: DeprecationWarning: object.__init__() takes no parameters
super(unicode2, self).__init__(other)
.\init.py:14: DeprecationWarning: object.__init__() takes no parameters
unicode.__init__(self, other)
为了举例说明这个问题,代码被简化了。在现实世界的应用程序中,我执行的不仅仅是调用super\uuuu init\uuuu
从前三行可以看出,unicode类实现了\uuuu init\uuuu
,并且该方法至少接受一个参数。但是,如果我想从子类调用该方法,无论是否调用super()
,我似乎都无法这样做
为什么可以在unicode实例上调用
unicode.\uuuuu init\uuuu
,但在unicode子类上却不能?如果对unicode类进行子类化,作者该怎么办?我怀疑问题的根源在于unicode
是不可变的
创建unicode
实例后,无法对其进行修改。因此,任何初始化逻辑都将位于\uuuuu new\uuuuu
方法中(调用该方法来创建实例),而不是\uuuuuu init\uuuu
(仅在实例存在后调用该方法)
不可变类型的子类没有相同的严格要求,因此您可以在unicode2中执行操作。如果您愿意,可以调用unicode。但是调用unicode是不必要的(并且可能不会执行您认为它会执行的操作)
更好的解决方案可能是使用自己的\uuuuuu新方法执行自定义逻辑:
class unicode2(unicode):
def __new__(cls, value):
# optionally do stuff to value here
self = super(unicode2, cls).__new__(cls, value)
# optionally do stuff to self here
return self
如果您愿意,您也可以通过给类一个总是引发异常的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>方法(您可能还希望给类一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.我怀疑这个问题是因为unicode
是不可变的
创建unicode
实例后,无法对其进行修改。因此,任何初始化逻辑都将位于\uuuuu new\uuuuu
方法中(调用该方法来创建实例),而不是\uuuuuu init\uuuu
(仅在实例存在后调用该方法)
不可变类型的子类没有相同的严格要求,因此您可以在unicode2中执行操作。如果您愿意,可以调用unicode。但是调用unicode是不必要的(并且可能不会执行您认为它会执行的操作)
更好的解决方案可能是使用自己的\uuuuuu新方法执行自定义逻辑:
class unicode2(unicode):
def __new__(cls, value):
# optionally do stuff to value here
self = super(unicode2, cls).__new__(cls, value)
# optionally do stuff to self here
return self
如果你愿意,你也可以通过给类一个总是引发异常的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>方法(你可能还想给类一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。。。为什么不能在内部使用Unicode字符串创建自定义类,有什么特别的原因吗?你可以很容易地让一个对象像Unicode字符串一样走路和说话。我不知道为什么会出现这种问题,但子类化Unicode似乎确实很不寻常。在一个完美的世界中,你应该能够子类化任何对象。当子类应充当字符串时,子类化字符串尤其有用。尝试模拟字符串的所有接口比简单的子类化要困难得多,也容易出错。例如,在没有子类化的情况下,如何实现一个类来为isinstance(my_subclass\u instance,basestring)
返回true?有关有用的示例,请参阅和。我还应该提到datetime.datetime
也存在同样的问题,因此它不是字符串所独有的。不确定为什么要显式调用unicode.\uuu init\uuu
。我认为如果您想替换底层字符串,那么使用集合.UserString
会更容易。我不认为您应该对字符串进行子类化。。。为什么不能在内部使用Unicode字符串创建自定义类,有什么特别的原因吗?你可以很容易地让一个对象像Unicode字符串一样走路和说话。我不知道为什么会出现这种问题,但子类化Unicode似乎确实很不寻常。在一个完美的世界中,你应该能够子类化任何对象。当子类应充当字符串时,子类化字符串尤其有用。尝试模拟字符串的所有接口比简单的子类化要困难得多,也容易出错。例如,在没有子类化的情况下,如何实现一个类来为isinstance(my_subclass\u instance,basestring)
返回true?有关有用的示例,请参阅和。我还应该提到datetime.datetime
也存在同样的问题,因此它不是字符串所独有的。不确定为什么要显式调用unicode.\uuu init\uuu
。我认为使用collections.UserString
会更容易,如果您想替换底层字符串的话。答案很好,但yoeur示例应该将str2
替换为unicode2
。或者直接调用unicode.\uuuuu new\uuuuu(cls,
)。哎呀,这是我从一个Python 3实现复制过来的一个打字错误(那里没有unicode
类)。我会更新。谢谢你的回答,但我认为这并不能解释为什么我可以在unicode实例上调用\uuuu init\uuuu
,但不能在unicode子类实例上调用。虽然unicode是不可变的,但仍然可以想象在\uu init\uuuu
期间会发生一些事情。在不了解底层实现的情况下,我运行了前三个lines的代码,并确认unicode.\uuuuu init\uuuu
似乎确实存在并接受参数,因此我希望避免在子类中抑制该方法。问题不是问如何对unicode进行子类化,而是为什么unicode.\uuu init\uuu
仅在子类中不起作用