I am trying to dynamically assign a class variable a value from inside of a class.
class Test:
dynamic_value = get_dynamic_value()
I believe get_dynamic_value()
should belong to the Test
class. Is there a way to have Test
contain this method?
Right now I am using and it is working
def get_dynamic_value():
return 'my dynamic value'
class Test:
dynamic_value = get_dynamic_value()
I would like for Test to contain this method so I have tried to make it both a @classmethod
and a @staticmethod
and calling it by
class Test:
dynamic_value = Test.get_dynamic_value()
@staticmethod
def get_dynamic_value():
return 'dynamic'
But when trying it using a static method I receive
AttributeError: class Test has no attribute 'get_dynamic_value'
Is there any way to do this? Or is there a better way to handle this?
Class suites evaluate from top to bottom, and the class you are defining does not exist until after the entire suite is evaluated.
You can put the function definition inside the class body, but you've got to call it after it's been defined, not before. So, this will work:
class Test:
def get_dynamic_value():
return 'dynamic'
dynamic_value = get_dynamic_value()
Marking the function as a staticmethod is not necessary; it's not used as a method at all, just a function that is called during the evaluation in the class suite. If you don't want the function to be available after the class is defined (as it isn't intended as a method), you can delete it.
class Test:
def get_dynamic_value():
return 'dynamic'
dynamic_value = get_dynamic_value()
del get_dynamic_value
If the value is really supposed to be dynamically calculated, every time you ask for it (so it is able to change from access to access), then you should use a property.
class Test:
@property
def dynamic_value(self):
return 'dynamic'
This would only be evaluate when accessed on a class instance, but the property object itself would exist on the class.
Just to add to Matt Anderson's answer - a workaround with class property:
class classproperty(property):
def __get__(self, cls, owner):
return classmethod(self.fget).__get__(None, owner)()
class Test:
@classproperty
def dynamic_value(cls):
return 'dynamic'
And a simple test:
In [102]: Test.dynamic_value
Out[102]: 'dynamic'