python类 返回属性值_在Python中,如何根据类方法的返回值初始化类属性?

本文讨论了如何在Python中为类创建枚举值,并将这些枚举值映射到键上。建议的方法是通过元类实现,这允许在类初始化时动态地将`get_choices()`返回的值关联到键。另外,对于Django应用,可以直接在`choices.py`文件中定义枚举并用于模型的映射,避免不必要的复杂性。
摘要由CSDN通过智能技术生成

1586010002-jmsa.png

Imagine we have this class:

class Custom:

@classmethod

def get_choices(cls):

# use cls attributes to return a list

mapping = {"key": ... }

I would like to associate the value returned by get_choices() to key. What code should go instead of the placeholder ... ?

EDIT: I wanted to keep the question context-agnostic (it seemed to me that this requirement was common enough, but I could be biased). As was suggested in comments, I will give some more details, because it seems we share the concern of 'most straightforward code':

I am working on a Django application, where I want to keep enumeration of values separated of the Models using them. What seemed to me like a natural solution was to create an enumeration.py module, where I could then define a class for each enumeration (the class having at least a class method to generate the collection of values). This is the get_choices() in the example.

Now, because of business logic, I need to map those choices to a key. This mapping being logically coupled to the enumeration, it seemed like a good structure to keep them together, in the same class (giving client code uniform and explicit access, being prefixed by the class name).

解决方案

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.

class CustomMetaClass(type):

def __init__(cls, classname, bases, attrs):

super(CustomMetaClass, cls).__init__(classname, bases, attrs)

cls.mapping['key'] = cls.get_choices()

class Custom(metaclass = CustomMetaClass): # assuming you are using python 3

mapping = {}

@classmethod

def get_choices(cls):

# add your custom code here

pass

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.

class CustomModelChoices(models.Model):

model_name = models.StringField(db_field = 'mn')

choices = models.DictField(db_field = 'ch')

class CustomModel(models.Model):

_choice_generator = CustomModelChoices

mapping = {

'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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值