Python类:为什么可以';我是否在_eq__(self,other)中使用len()方法?

Python类:为什么可以';我是否在_eq__(self,other)中使用len()方法?,python,class,python-2.7,oop,variable-length,Python,Class,Python 2.7,Oop,Variable Length,在iPython中调用: In [2]: a = ['a','b'] In [3]: b = ['b','a'] In [4]: c = ['a','b'] In [5]: a == b Out[5]: False In [6]: FrozenSortedTuple(a) Out[6]: <__main__.FrozenSortedTuple instance at 0x103c56200> In [7]: fa = FrozenSortedTuple(a) In [8]

在iPython中调用:

In [2]: a = ['a','b']

In [3]: b = ['b','a']

In [4]: c = ['a','b']

In [5]: a == b
Out[5]: False

In [6]: FrozenSortedTuple(a)
Out[6]: <__main__.FrozenSortedTuple instance at 0x103c56200>

In [7]: fa = FrozenSortedTuple(a)

In [8]: fb = FrozenSortedTuple(b)

In [9]: fa == fb
[2]中的
:a=['a','b']
在[3]中:b=['b','a']
在[4]中:c=['a','b']
在[5]中:a==b
Out[5]:假
在[6]中:FrozenSortedTuple(a)
出[6]:
在[7]中:fa=冻结排序的整数(a)
在[8]中:fb=FrozenSortedTuple(b)
在[9]中:fa==fb
错误:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-317181571e4d> in <module>()
----> 1 fa == fb

<ipython-input-1-ef99f0af5061> in __eq__(self, other)
     15 
     16   def __eq__(self, other):
---> 17     if len(self.vals) != len(other):
     18       return False
     19     if type(self.vals) != type(other):

AttributeError: FrozenSortedTuple instance has no attribute '__len__'
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
在()
---->1 fa==fb
in__eq__;(自我、其他)
15
16定义均衡(自身、其他):
--->17如果len(self.vals)!=len(其他):
18返回错误
19如果类型(自身VAL)!=类型(其他):
AttributeError:FrozenSortedTuple实例没有属性“\uu len\uu”

我很困惑。

如果您试图直接比较两个FrozenSortedTuples值的结构和内容,请将
other
的所有实例更改为
other.vals

def __eq__(self, other):
    if len(self.vals) != len(other.vals):
      return False
    if type(self.vals) != type(other.vals):
      return False
    if type(other.vals) not in [list, set, tuple]:
      return False
    other_list = list(other.vals)
    for i,item in enumerate(self.vals):
      if item != other_list[i]:
        return False
    return True

当然,如果
other
不是FrozenSortedTuple,这将无法工作。例如,
fa==23
将不起作用,因为数字23没有“vals”属性。

按照您定义
\uuuueq\uuuuuuu(self,other)
的方式,只有当other是您正在包装的类型的实例(即list、set或tuple)时,才能实现相等。通过比较
FrozenSortedTuple
的两个实例触发错误。错误消息告诉您无法在这样的实例上调用len(),这是因为您尚未在类中定义方法
\uuu len\uuu(self)

如果为类定义
\uuuu len\uuuu()
,它将起作用。请参阅(此链接指向2.7文档,但在Python3.x中应与之相同)
或者,您可以比较
len(self.vals)==len(other.vals)
来比较
FrozenSortedTuple
实例。

谢谢,基于其他答案,我想要的是:

class FrozenSortedTuple:
  """A frozenset that cares about order of tuples. And is not actually frozen."""
  def __init__(self, vals):
    if type(vals) not in [list, set, tuple]:
      raise Exception('Value not a list or set')
    self.vals = vals

  def __len__(self):
    return len(self.vals)

  def __iter__(self):
    return iter(self.vals)

  def __getitem__(self, key):
    return list(self.vals)[key]

  def __eq__(self, other):
    if len(self) != len(other):
      print "len(self)"
      return False

    for i,item in enumerate(self.vals):
      if item != other[i]:
        return False
    return True

  def __str__(self):
    str_val = str()
    for val in self:
      str_val += str(val)
    return str_val

  def __hash__(self):
    return hash(str(self))
测试:

# FrozenSortedTuple Tests
a = ['a','b']
b = ['b','a']
c = ['a','b']

fa = FrozenSortedTuple(a)
fb = FrozenSortedTuple(b)
fc = FrozenSortedTuple(c)

fa == fb
fa == fc
fa == ['a','b']
fa == ['b','a']
fa == ('a','b')
fa == ('b','a')

a = set([fa, fb, fc])
b = set([fa, fb, fc])
c = set([fa, fc, fb])
a == b
b == c
fa in a
fb in b

d = set([fb])
fa in d

问题不是“你不能在
\uuuu eq\uuuu
内部调用
len
”。问题是“你根本不能在任何地方调用
len
”,因为你从来没有为这个类实现过它
len(fa)
在主作用域中也会以同样的方式失败。为什么所有的全局函数都会在一个类中消失?哦!我明白了。谢谢,等等,我不知道。我在调用len()而不是self,或者是。。。是的,我是。好的,谢谢!您可以在回答中而不是在注释中做出答案吗?或者只实现
def\uu len\uuuu(self):返回len(self.vals)
。是的,但是如果键入(self.vals)!=键入(other)将无法按预期工作,依此类推所有其他条件。是的,代码的其余部分当然需要相应地进行调整。
# FrozenSortedTuple Tests
a = ['a','b']
b = ['b','a']
c = ['a','b']

fa = FrozenSortedTuple(a)
fb = FrozenSortedTuple(b)
fc = FrozenSortedTuple(c)

fa == fb
fa == fc
fa == ['a','b']
fa == ['b','a']
fa == ('a','b')
fa == ('b','a')

a = set([fa, fb, fc])
b = set([fa, fb, fc])
c = set([fa, fc, fb])
a == b
b == c
fa in a
fb in b

d = set([fb])
fa in d