Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__getattr__ on a class and not (or as well as) an instance

Tags:

python

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.

like image 412
user1537607 Avatar asked Jan 16 '23 01:01

user1537607


1 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'
like image 56
mouad Avatar answered Jan 27 '23 20:01

mouad