__getattr__ on a class and not (or as well as) an instance
I know I can write code like:
class A : def __getattr__ (self, name) : return name
to trap access to undefined attributes on an instance of a class, so:
A().ATTR == 'ATTR'
is True. But is there any way to do this for the class itself? What I'd like to be able to is to have the following two lines both work, and be distinguishable (ie., there are different magic methods called, or the magic method can tell how it was called)
a = A().ATTR b = A.ATTR
I suspect the answer is no but maybe there is some deep python ju-ju?
Edit: The actual problem is extending a custom active record library in a backwards-compatible way. The ORM code supports code along the lines of
ar = AR_people() ar.find() name = ar.name
to access tables, where name may get mapped to a column name which is different, e.g. pe_name. We want to be able to write something like
ar.filter(AR_people.age >= 21)
and end up with
pe_age >= 21
(much like other ORM libraries do), so AR_people.age needs to return an instance of a class that implements __ge__ and so forth to do the conversion magic.
You can use a metaclass:
In : class meta(type): ...: def __getattr__(self, name): ...: return name ...: ...: In : class A(object): ...: __metaclass__ = meta ...: def __getattr__(self, name): ...: return name ...: ...: In : A().attr Out: 'attr' In : A.attr Out: 'attr'
Yes you can. Metaclasses are the answer.
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