Python 如何更改实例(不在类中)的_cmp__函数?
如何更改实例(不在类中)的_cmp__函数 例:Python 如何更改实例(不在类中)的_cmp__函数?,python,metaprogramming,cmp,Python,Metaprogramming,Cmp,如何更改实例(不在类中)的_cmp__函数 例: foo类: 定义初始化(self,num): self.num=num def cmp(自身、其他): 返回self.num-other.num #更改类工作中的cmp函数 foo.\uuuucmp\uuuuuu=cmp a=foo(1) b=foo(1) #返回True a==b #在实例中更改_cmp______)函数,这样做不起作用 def cmp2(自身、其他): 返回-1 a、 _u_cmp_uuu=cmp2 b、 _u_cmp_uuu
foo类:
定义初始化(self,num):
self.num=num
def cmp(自身、其他):
返回self.num-other.num
#更改类工作中的cmp函数
foo.\uuuucmp\uuuuuu=cmp
a=foo(1)
b=foo(1)
#返回True
a==b
#在实例中更改_cmp______)函数,这样做不起作用
def cmp2(自身、其他):
返回-1
a、 _u_cmp_uuu=cmp2
b、 _u_cmp_uuu=cmp2
#提出错误
a==b
#回溯(最近一次呼叫最后一次):
#文件“”,第1行,在
#TypeError:cmp2()正好接受2个参数(给定1个)
不要这样做
这将使您的代码出现错误,难以维护。它之所以困难,是因为正确的方法是将foo子类化:
class FunkyCmpFoo( foo ):
def __cmp__( self, other ):
return -1
&c、 和c。这样,您就知道所有foo
s都以相同的方式进行比较,而所有FunkyCmpFoo
s都以相同的方式进行比较。如果你不这样做,你最终会将一个修改过的foo
与一个原始的foo
进行比较,而Cthulhu自己会从深处站起来惩罚你
我不确定是否应该这样说,但是,通过创建您自己的:
我可以想出这样做的一个很好的理由,那就是如果你的大敌必须调试代码。事实上,我可以想到一些非常有趣的事情来做(您希望sys.maxint
如何比较小于所有偶数的数字?)。除此之外,这是一场噩梦。编辑:如果在生产代码中这样做,我应该说你是一个坏人。你所有的头发和牙齿都会脱落,你将被诅咒在你的来世中永远走在这堆东西上
添加额外的间接寻址,这样就不会混淆绑定/未绑定方法:
class foo(object):
def __init__(self, num):
self.num = num
self.comparer = self._cmp
def __cmp__(self, other):
return self.comparer(self, other)
@staticmethod
def _cmp(this, that):
print 'in foo._cmp'
return id(this) == id(that)
def setcmp(self, f):
self.comparer = f
def cmp2(self, other):
print 'in cmp2'
return -1
a = foo(1)
b = foo(1)
print a == b
a.setcmp(cmp2)
b.setcmp(cmp2)
print a == b
*您可以使用反多晶硅模式:
class foo(object):
def __init__(self, num, i_am_special=None):
self.num = num
self.special = i_am_special
def __cmp__(self, other):
if self.special is not None:
return -1
else:
return cmp(self.num, other.num)
def __hash__(self):
if self.special is not None:
# TODO: figure out a non-insane value
return 0
这会产生如下合理结果:
>>> a = foo(1)
>>> b = foo(2, 'hi mom')
>>> a > b
False
>>> b > a
False
>>> a == b
False
>>> b == b
False
我之所以发布这个答案,主要是因为我喜欢“反多晶硅”的发音。不要在家里这样做,孩子们没有适当的成人监督
[*未经许可使用的恐怖标志编码,或我确信是很棒的家伙的权利持有人,不需要像这样玷污他们的标志。]虽然通常为类的不同实例更改比较函数是不好的做法,有时,您可能希望对要对其执行公共操作的一组实例使用不同的比较函数。例如,您希望根据不同的标准对它们进行排序
标准示例是排序(列出\u foos,cmp=foocmp)
。尽管目前首选使用键
参数,但实际上Python 3.x无论如何都不支持cmp
参数(您可能希望使用cmp\u to\u键
)
在这种情况下,最好的方法通常是使比较函数成为在实例组上操作的函数的参数,与排序后的
完全相同。您的类应该继承自对象
:类foo(对象):
同一类(~类实例)的不同比较例程?为什么?+1只是因为引起了一些非常棒的答案=p你至少应该说不要那样做,否则实际上有人可能会=p谢谢!我不会在一个“真正的”代码,这只是为了好玩。
class foo(object):
def __init__(self, num, i_am_special=None):
self.num = num
self.special = i_am_special
def __cmp__(self, other):
if self.special is not None:
return -1
else:
return cmp(self.num, other.num)
def __hash__(self):
if self.special is not None:
# TODO: figure out a non-insane value
return 0
>>> a = foo(1)
>>> b = foo(2, 'hi mom')
>>> a > b
False
>>> b > a
False
>>> a == b
False
>>> b == b
False