有没有办法将__len__或__eq__等方法实现为classmethods?

iko*_*tia 39 python class

__len__(self)在Python中实现方法非常容易,因此它可以处理这样的len(inst)调用:

class A(object):

  def __len__(self):
    return 7

a = A()
len(a) # gives us 7
Run Code Online (Sandbox Code Playgroud)

而且有很多相似的方法,你可以定义(__eq__,__str__,__repr__等).我知道Python类也是对象.

我的问题:我可以以某种方式定义,例如,__len__以便以下工作:

len(A) # makes sense and gives some predictable result
Run Code Online (Sandbox Code Playgroud)

Eli*_*ins 43

你正在寻找被称为"元类"什么......就像a是类的一个实例A,A是类的一个实例为好,被称为元类.默认情况下,Python类是类的实例type(唯一的例外是在Python 2下,它有一些遗留的"旧式"类,它们是那些不继承的类object).您可以通过执行来检查type(A)...它应该返回type自己(是的,该对象已经过载了一点).

元类是强大的,大脑扭曲足以得到比我即将写的快速解释更多...一个好的起点将是这个stackoverflow问题:什么是元类.

对于您的特定问题,对于Python 2,下面创建了一个元类,该别名len(A)用于在A上调用类方法:

class LengthMetaclass(type):

    def __len__(self):
        return self.clslength()

class A(object):
    __metaclass__ = LengthMetaclass

    @classmethod
    def clslength(cls):
        return 7

print len(A)
Run Code Online (Sandbox Code Playgroud)

Python 3的工作方式类似,但您可以使用class A(object, metaclass=LengthMetaclass):而不是__metaclass__ = LengthMetaclass.

原因LengthMetaclass.__len__不影响实例,A即Python中的属性解析首先检查实例dict,然后遍历类层次结构[A, object],但它从不参与元类.而访问A.__len__首先参考实例A,然后走它的类层次结构,其中包括[LengthMetaclass, type].


Ery*_*Sun 5

由于类是元类的实例,因此一种方法是使用自定义元类:

>>> Meta = type('Meta', (type,), {'__repr__': lambda cls: 'class A'})
>>> A = Meta('A', (object,), {'__repr__': lambda self: 'instance of class A'})
>>> A
class A
>>> A()
instance of class A
Run Code Online (Sandbox Code Playgroud)