下面的代码有效(编辑:实际上,事实证明它不起作用!),但我不喜欢出现在try: except:
块之后的挂起return True
语句。在
class MySlottedClass(object):
def __new__(klass, **slots):
klass.__slots__ = []
for k in slots:
klass.__slots__.append(k)
return super(MySlottedClass,klass).__new__(klass)
def __init__(self, **slots):
for k,v in slots.items():
setattr(self,k,v)
super(MySlottedClass,self).__new__()
def __eq__(self, other):
for slot in self.__slots__:
try:
assert getattr(self, slot) == getattr(other,slot), "Not Equal"
except (AssertionError, AttributeError):
return False
return True
##Testing
##Note that the above class definition is just a skeleton
##The below objects are created using 4 different but identically defined classes
##In the actual problem, I am using a metaclass to make these classes dynamically
msc1 = MySlottedClassABC(a=1,b=1,c=3)
msc2 = MySlottedClassAB(a=1,b=1)
msc3 = MySlottedClassBA(b=2,a=1)
msc4 = MySlottedClassXY(x=1,y=2)
assert msc1!=msc2
assert msc2==msc3
assert msc3==msc2
assert msc2!=msc4
为这个类编写__eq__
方法有没有更为python式的方法?在
似乎您正在尝试重新创建^{} 。使用
namedtuple
将允许在上动态创建类、测试相等性和其他有趣的事情。缺点是,由于元组是不可变的,所以to是namedtuples,因此必须创建一个新对象,而不是更新属性。{slot{or你的slots}顺序不能同时检查。在用法示例:
如果插槽的顺序和易变性很重要,那么下面的工作就可以了(对于python2)。在
^{pr2}$这项研究指出
__slots__
在几乎所有情况下都是过度杀伤。Guido Van Rossum指出,基于对新样式类中属性查找性能的无根据担忧,它们是一个过早的优化。Guido还声明,__slots__
可以减少程序的内存占用,当您需要创建小对象的时候。在http://python-history.blogspot.co.uk/2010/06/inside-story-on-new-style-classes.html
呃,我从没想过。很明显:
我可能应该结束这个问题,这样我就不会显得太傻了。编辑:不,不好!在
多亏了大家的帮助,我现在才明白,用这种方式做事有很多问题。首先,我不应该为此使用
assert
,因为它主要用于测试,并且可以关闭。其次,代码没有给出MySlottedClass(a=1,b=2)==MySlottedClass(a=1,b=2,c=3)
的预期结果。在我想出了这个办法。请注意,类定义重复了4次,这样我就可以测试下面不同类的对象的比较;但是,在创建它们的实例之前,所有类都是相同的。还要注意,在实际的用例中,我使用元类自动生成这些类(并且
^{pr2}$__eq__
被定义为该元类的一部分)。在测试步骤如下:
然而,在测试了Joran Beasley's answer之后,我惊讶地发现,它生成的结果与上面的结果完全相同,代码更短、更合理。因此,实现这一点的最佳方法似乎是简单地比较两个
__dict__
属性。在return True
很好。我认为更大的问题是使用assert
进行流控制。如果用户在命令行上将-O
传递给python
,则断言根本不运行。你应该写更多这样的东西:另外,
^{pr2}$__slots__
需要在类级别定义才能工作,而不是在__init__
内部定义:如果项目数可变,则可能根本不应该使用
__slots__
。在相关问题 更多 >
编程相关推荐