Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a method like '__getattribute__' for class (not instance) variables?

Tags:

python

I have a class sysprops in which I'd like to have a number of constants. However, I'd like to pull the values for those constants from the database, so I'd like some sort of hook any time one of these class constants are accessed (something like the getattribute method for instance variables).

class sysprops(object):
    SOME_CONSTANT = 'SOME_VALUE'

sysprops.SOME_CONSTANT  # this statement would not return 'SOME_VALUE' but instead a dynamic value pulled from the database.
like image 970
Trevor Avatar asked Mar 05 '13 01:03

Trevor


People also ask

What is the difference between Getattr and Getattribute?

getattribute: Is used to retrieve an attribute from an instance. It captures every attempt to access an instance attribute by using dot notation or getattr() built-in function. getattr: Is executed as the last resource when attribute is not found in an object.

What is __ Getattribute __?

__getattribute__ This method should return the (computed) attribute value or raise an AttributeError exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.

What is special method?

In Python, special methods are a set of predefined methods you can use to enrich your classes. They are easy to recognize because they start and end with double underscores, for example __init__ or __str__ .

What are __ methods in Python?

The __call__ method enables Python programmers to write classes where the instances behave like functions. Both functions and the instances of such classes are called callables.


2 Answers

While the other two answers have a valid method. I like to take the route of 'least-magic'.

You can do something similar to the metaclass approach without actually using them. Simply by using a decorator.

def instancer(cls):
    return cls()

@instancer
class SysProps(object):
    def __getattribute__(self, key):
        return key # dummy

This will create an instance of SysProps and then assign it back to the SysProps name. Effectively shadowing the actual class definition and allowing a constant instance.

Since decorators are more common in Python I find this way easier to grasp for other people that have to read your code.

like image 27
Wessie Avatar answered Sep 21 '22 09:09

Wessie


Although I think it is a very bad idea to do this, it is possible:

class GetAttributeMetaClass(type):
    def __getattribute__(self, key):
        print 'Getting attribute', key

class sysprops(object):
    __metaclass__ = GetAttributeMetaClass
like image 170
Wolph Avatar answered Sep 23 '22 09:09

Wolph