是否可以修改len()的行为?

时间:2015-05-27 13:21:14

标签: python python-3.x

我知道创建自定义user_id__repr__方法(等等),以修改运算符和函数的行为。是否有__add__的方法覆盖?

例如:

len

是否可以使用列表为class Foo: def __repr__(self): return "A wild Foo Class in its natural habitat." foo = Foo() print(foo) # A wild Foo Class in its natural habitat. print(repr(foo)) # A wild Foo Class in its natural habitat. 执行此操作?通常,它看起来像这样:

len

如果我想让搜索类型超出计数范围怎么办?像这样:

foo = []
print(len(foo))    # 0

foo = [1, 2, 3]
print(len(foo))    # 3

有没有办法在class Bar(list): pass foo = [Bar(), 1, ''] print(len(foo)) # 3 count = 0 for item in foo: if not isinstance(item, Bar): count += 1 print(count) # 2 子类中执行此操作?

4 个答案:

答案 0 :(得分:19)

是的,实施__len__ method

def __len__(self):
    return 42

演示:

>>> class Foo(object):
...     def __len__(self):
...         return 42
... 
>>> len(Foo())
42

来自文档:

  

被调用以实现内置函数len()。应返回对象的长度,为整数>= 0.此外,未定义__bool__()方法且其__len__()方法返回零的对象在a中被视为false布尔上下文。

针对您的具体情况:

>>> class Bar(list):
...     def __len__(self):
...         return sum(1 for ob in self if not isinstance(ob, Bar))
... 
>>> len(Bar([1, 2, 3]))
3
>>> len(Bar([1, 2, 3, Bar()]))
3

答案 1 :(得分:7)

是的,正如您已经发现可以通过实施repr()魔术方法来覆盖__repr__函数调用的行为,您可以从len()函数指定行为通过实施(惊喜)然后__len__魔术召唤:

>>> class Thing:
...     def __len__(self):
...         return 123
...     
>>> len(Thing())
123

一个学究者可能会提到你没有修改len()的行为,你正在修改你班级的行为。 len只是做它一直做的事情,包括检查参数的__len__属性。

答案 2 :(得分:5)

请记住:Python是动态和Duck Typed语言。

如果它的行为类似于可能有长度的东西;

class MyCollection(object):

    def __len__(self):
        return 1234

示例:

>>> obj = MyCollection()
>>> len(obj)
1234

如果它没有表现得有长度; KABOOM!

class Foo(object):

    def __repr___(self):
        return "<Foo>"

示例:

>>> try:
...     obj = Foo()
...     len(obj)
... except:
...     raise
... 
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
TypeError: object of type 'Foo' has no len()

来自Typing

  

Python使用duck typing并且有类型对象但是无类型变量   名。在编译时不检查类型约束;相反,   对象上的操作可能会失败,表示给定的对象是   不是合适的类型。尽管是动态类型,但Python是   强类型,禁止未明确定义的操作(for   例如,向字符串添加数字而不是静默尝试   理解它们。

示例:

>>> x = 1234
>>> s = "1234"
>>> x + s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

答案 3 :(得分:3)

您只需在课程中添加__len__方法即可。

class Test:
    def __len__(self):
        return 2

a=Test()
len(a) # --> 2
相关问题