Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can I implement a class method dynamically in Python?

In Python, it’s no secret that you can implement attributes of an instance of a class dynamically. Here’s what that looks like:

class MyClass(object):
    def __getattribute__(self, name):
        if name == 'dynamic_attribute':
            return "dynamic attribute value"
        return super().__getattribute__(name)

# Create an instance of my class
obj = MyClass()

# I've implemented the 'dynamic_attribute' attribute dynamically, so I can
# reference it without ever having assigned it a value
print(obj.dynamic_attribute)

# As I've only implemented that one attribute dynamically, other attributes
# behave in the standard way
try:
    print(obj.regular_attribute)
except AttributeError as ex:
    print(f"EXPECTED ERROR: {ex}")
obj.regular_attribute = "regular attribute value"
print(obj.regular_attribute)

Result:

dynamic attribute value
EXPECTED ERROR: 'MyClass' object has no attribute 'regular_attribute'
regular attribute value

Is there any way to do this same thing with a class attribute rather than a class instance attribute? Here’s an example:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

print(MyClass.dynamic_class_attribute)

I want this line of code to return a value that is computed somewhere in my code without me having to have defined a ‘dynamic_class_attribute’ attribute explicitly on the MyClass class. Can this be done? TIA.

PS: I’ve never done anything with metaclasses, but I know of their existence. I read up a little on them hoping for an obvious answer to this question. I didn’t find one.

>Solution :

Is there any way to do this same thing with a class attribute rather than a class instance attribute?

Yes, just move the logic into a metaclass:

class MyMetaClass(type):
    def __getattribute__(self, name):
        if name == 'dynamic_attribute':
            return "dynamic attribute value"
        return super().__getattribute__(name)

class C(metaclass=MyMetaClass):
    pass

print(C.dynamic_attribute)

The basic idea is that regular classes control the behavior of instances and metaclasses control the behavior of classes.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading