我正在尝试在Python中扩展一些"基础"类:
class xlist (list): def len(self): return len(self) def add(self, *args): self.extend(args) return None class xint (int): def add(self, value): self += value return self x = xlist([1,2,3]) print x.len() ## >>> 3 ok print x ## >>> [1,2,3] ok x.add (4, 5, 6) print x ## >>> [1,2,3,4,5,6] ok x = xint(10) print x ## >>> 10 ok x.add (2) print x ## >>> 10 # Not ok (#1) print type(x) ## >>>ok x += 5 print type(x) ## >>> # Not ok (#2)
它在列表情况下工作正常,因为append方法"就地"修改了对象,而没有返回它.但在int情况下,add方法不会修改外部x变量的值.我认为在类的add方法中self是局部变量的意义上很好,但这阻止我修改分配给类实例的初始值.
是否可以通过这种方式扩展类,还是应该使用基类型定义类属性并将所有需要的方法映射到此属性?
您的两个xint
示例由于两个不同的原因而不起作用.
第一个不起作用,因为self += value
它等效于self = self + value
将局部变量重新分配self
给不同的对象(整数)但不更改原始对象.你真的不能得到这个
>>> x = xint(10) >>> x.add(2)
使用子类,int
因为整数是不可变的.
要使第二个工作,您可以定义一个__add__
方法,如下所示:
class xint(int): def __add__(self, value): return xint(int.__add__(self, value)) >>> x = xint(10) >>> type(x)>>> x += 3 >>> x 13 >>> type(x)
int是一个值类型,因此每次执行赋值时(例如,+ =上面的两个实例),它都不会修改堆上的对象,而是用右手的结果之一替换引用赋值的一面(即一个int)
list不是值类型,因此它不受相同规则的约束.
此页面提供了有关差异的更多详细信息:http://docs.python.org/ref/objects.html
IMO,是的,您应该定义一个新的类,将int保存为实例变量