4

我知道我可以编写如下代码:

class A :
    def __getattr__ (self, name) :
        return name

捕获对类实例上未定义属性的访问,因此:

A().ATTR == 'ATTR'

True。但是有什么办法可以为班级本身做到这一点吗?我希望能够使以下两行都可以工作,并且可以区分(即,有不同的魔术方法被调用,或者魔术方法可以告诉它是如何被调用的)

a = A().ATTR
b = A.ATTR

我怀疑答案是否定的,但也许有一些深巨蟒?

编辑:实际问题是以向后兼容的方式扩展自定义活动记录库。ORM 代码支持如下代码:

ar = AR_people()
ar.find()
name = ar.name

访问表,其中name可能会映射到不同的列名,例如pe_name. 我们希望能够写出类似的东西

ar.filter(AR_people.age >= 21)

最后得到

pe_age >= 21

(很像其他 ORM 库所做的),所以AR_people.age需要返回一个实现的类的实例__ge__等等来做转换魔术。

4

2 回答 2

7

您可以使用元类

In [1]: class meta(type):
   ...:     def __getattr__(self, name):
   ...:         return name
   ...:     
   ...:     

In [2]: class A(object):
   ...:     __metaclass__ = meta
   ...:     def __getattr__(self, name):
   ...:         return name
   ...:     
   ...:     

In [3]: A().attr
Out[3]: 'attr'

In [4]: A.attr
Out[4]: 'attr'
于 2012-07-19T10:47:12.103 回答
2

是的你可以。元类就是答案。

class MyMetaclass(type):
    def __getattr__(cls, name):
        return "cls.%s" % name


class A :
    __metaclass__ = MyMetaclass
    def __getattr__ (self, name) :
        return name

print A().ATTR
print A.ATTR

将输出

ATTR
cls.ATTR
于 2012-07-19T10:52:50.027 回答