Python 从不可变 class int 继承,为什么参数的顺序在复制时很重要?
Python Inheritance from immutable class int, why arguments' order matters when copying?
我正在尝试实现一个从 int 继承的 class,并向其添加一些成员,但我发现派生 class 的实例无法正确复制(即使是深层复制)如果参数的顺序发生变化,请参见下面的示例,尝试创建一个正整数 class:
# Example 1
import copy as cp
class PositiveInt(int):
def __new__(cls, arg = 1, arg0 = 2, arg1 = 3):
if arg < 0:
arg = -arg
return super(PositiveInt, cls).__new__(cls, arg)
def __init__(self, arg = 1, arg0 = 2, arg1 = 3):
self.arg0 = arg0
self.arg1 = arg1
n = PositiveInt(3, 4, 5)
m = cp.copy(n)
print(n, n.arg0, n.arg1)
print(m, m.arg0, m.arg1)
这将打印:
(3, 4, 5)
(3, 4, 5)
# Example 2
class PositiveInt(int):
def __new__(cls, arg0 = 2, arg = 1, arg1 = 3):
if arg < 0:
arg = -arg
return super(PositiveInt, cls).__new__(cls, arg)
def __init__(self, arg0 = 2, arg = 1, arg1 = 3):
self.arg0 = arg0
self.arg1 = arg1
n = PositiveInt(4, 3, 5)
m = cp.copy(n)
print(n, n.arg0, n.arg1)
print(m, m.arg0, m.arg1)
这将打印:
(3, 4, 5)
(1, 4, 5)
唯一的区别是参数的顺序。好像在例2中,copy会在new中使用arg的默认值进行实例化,但在例1中并不是这样。
m = cp.copy(n)
最终调用 m = PositiveInt(n)
而后者又调用 m=PositiveInt(3)
你可以继承 __copy__
def __copy__(self):
return PositiveInt(self.arg0,self,self.arg1)
或者您可以检查 __new__
中的第一个参数(也许...我实际上认为这行不通)...但实际上您应该只继承 __copy__
我正在尝试实现一个从 int 继承的 class,并向其添加一些成员,但我发现派生 class 的实例无法正确复制(即使是深层复制)如果参数的顺序发生变化,请参见下面的示例,尝试创建一个正整数 class:
# Example 1
import copy as cp
class PositiveInt(int):
def __new__(cls, arg = 1, arg0 = 2, arg1 = 3):
if arg < 0:
arg = -arg
return super(PositiveInt, cls).__new__(cls, arg)
def __init__(self, arg = 1, arg0 = 2, arg1 = 3):
self.arg0 = arg0
self.arg1 = arg1
n = PositiveInt(3, 4, 5)
m = cp.copy(n)
print(n, n.arg0, n.arg1)
print(m, m.arg0, m.arg1)
这将打印:
(3, 4, 5)
(3, 4, 5)
# Example 2
class PositiveInt(int):
def __new__(cls, arg0 = 2, arg = 1, arg1 = 3):
if arg < 0:
arg = -arg
return super(PositiveInt, cls).__new__(cls, arg)
def __init__(self, arg0 = 2, arg = 1, arg1 = 3):
self.arg0 = arg0
self.arg1 = arg1
n = PositiveInt(4, 3, 5)
m = cp.copy(n)
print(n, n.arg0, n.arg1)
print(m, m.arg0, m.arg1)
这将打印:
(3, 4, 5)
(1, 4, 5)
唯一的区别是参数的顺序。好像在例2中,copy会在new中使用arg的默认值进行实例化,但在例1中并不是这样。
m = cp.copy(n)
最终调用 m = PositiveInt(n)
而后者又调用 m=PositiveInt(3)
你可以继承 __copy__
def __copy__(self):
return PositiveInt(self.arg0,self,self.arg1)
或者您可以检查 __new__
中的第一个参数(也许...我实际上认为这行不通)...但实际上您应该只继承 __copy__