In Python, How To Initialize A Class Attribute From The Return Value Of A Class Method?
Solution 1:
You cannot do it in class definition because class object has not been created yet. After the class definition, you could definitely do something like this -
Custom.mapping['key'] = Custom.get_choices()
Although the recommended way to do this would be to use a metaclass.
classCustomMetaClass(type):
def__init__(cls, classname, bases, attrs):
super(CustomMetaClass, cls).__init__(classname, bases, attrs)
cls.mapping['key'] = cls.get_choices()
classCustom(metaclass = CustomMetaClass): # assuming you are using python 3
mapping = {}
@classmethoddefget_choices(cls):
# add your custom code herepass
With that said, that is an Object Oriented solution to the problem. you can ofcourse use some function to generate choices thus ending the need to use metaclass.
For Edited Question:-
In that case, I think you should just maintain a file named 'choices.py' as you yourself suggested and use them in your mapping, instead of get_choices
class method. You don't need to unnecessarily make classes for each model if all you want to do is store choices. Just use dicts and constants.
If your classes needs to be generated dynamically, say from db, then you need to create separate model for storing choices.
classCustomModelChoices(models.Model):
model_name = models.StringField(db_field = 'mn')
choices = models.DictField(db_field = 'ch')
classCustomModel(models.Model):
_choice_generator = CustomModelChoicesmapping= {
'key': CustomModelChoices.objects.get(model_name = 'CustomModel').choices
}
This is just a raw design, might need to be improved a lot, but something on these lines.
Solution 2:
If the logic you need to run is trivial then just putting the logic directly after the class is fine:
classCustom1:
value = 1@classmethod
def get_choices(cls):
return [cls.value]
Custom1.mapping = {"key": Custom1.get_choices()}
If the logic is more complicated, and especially if needed by multiple classes, then a decorator could be useful. eg
defadd_mapping_choices(cls):
cls.mapping = {"key": cls.get_choices()}
return cls
@add_mapping_choicesclassCustom2:
value = 2 @classmethoddefget_choices(cls):
return [cls.value]
Post a Comment for "In Python, How To Initialize A Class Attribute From The Return Value Of A Class Method?"