是否有一种方法来实现像__len__或__eq__作为类方法? [英] Is there a way to implement methods like __len__ or __eq__ as classmethods?

查看:147
本文介绍了是否有一种方法来实现像__len__或__eq__作为类方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python中实现 __ len __(self)方法很容易,因此它可以处理 len(inst)调用像这样:

It is pretty easy to implement __len__(self) method in Python so that it handles len(inst) calls like this one:

class A(object):

  def __len__(self):
    return 7

a = A()
len(a) # gives us 7

$ b b

有很多类似的方法可以定义( __ eq __ __ str __ code> __ repr __ 等)。
我知道Python类也是对象。

And there are plenty of alike methods you can define (__eq__, __str__, __repr__ etc.). I know that Python classes are objects as well.

我的问题:我可以以某种方式定义,例如 __ len __ ,以使以下工程:

My question: can I somehow define, for example, __len__ so that the following works:

len(A) # makes sense and gives some predictable result


推荐答案

你正在寻找的是一个元类...就像 a 类的实例, A 也是类的实例,称为元类。默认情况下,Python类是类型类的实例(唯一的例外是在Python 2下,它有一些旧的旧样式类,继承自 object )。你可以通过 type(A)来检查这一点,它应该返回 type

What you're looking for is called a "metaclass"... just like a is an instance of class A, A is an instance of class as well, referred to as a metaclass. By default, Python classes are instances of the type class (the only exception is under Python 2, which has some legacy "old style" classes, which are those which don't inherit from object). You can check this by doing type(A)... it should return type itself (yes, that object has been overloaded a little bit).

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

Metaclasses are powerful and brain-twisting enough to deserve more than the quick explanation I was about to write... a good starting point would be this stackoverflow question: What is a Metaclass.

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

For your particular question, for Python 2, the following creates a metaclass which aliases len(A) to invoke a class method on A:

class LengthMetaclass(type):

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

class A(object):
    __metaclass__ = LengthMetaclass

    @classmethod
    def clslength(cls):
        return 7

print len(A)

Python 3的工作方式类似,将使用类A(object,metaclass = LengthMetaclass):而不是 __ metaclass__ = LengthMetaclass

Python 3 works similarly, but you would use class A(object, metaclass=LengthMetaclass): instead of __metaclass__ = LengthMetaclass.

原因 LengthMetaclass .__ len __ 不会影响 A 实例 c $ c>是Python中的属性解析首先检查实例dict,然后遍历类层次结构 [A,object] ,但它从不参考元类。而访问 A .__ len __ 首先查询实例 A ,然后走 其中包含 [LengthMetaclass,type]

The reason LengthMetaclass.__len__ doesn't affect instances of A is that attribute resolution in Python first checks the instance dict, then walks the class hierarchy [A, object], but it never consults the metaclasses. Whereas accessing A.__len__ first consults the instance A, then walks it's class hierarchy, which consists of [LengthMetaclass, type].

这篇关于是否有一种方法来实现像__len__或__eq__作为类方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆