__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.

Answers


You can use a metaclass:

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'

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

will output

ATTR
cls.ATTR

Need Your Help

TPL dataflow and BatchJoinBlock with different batch sizes

c# .net parallel-processing task-parallel-library tpl-dataflow

Let's say I have some data coming from 2 different sources at 2 different frequencies and I have to join them and process them together. Frequency on channel A is 100Hz (100 integers per second), w...

Apache: Deploying a new site to the server

apache deployment indexing shared-hosting

I have a site currently live on a domain. I would like to switch it to a new site, that is currently in a password protected sub directory on this server.