簡體   English   中英

在Python中,如何從類方法的返回值初始化類屬性?

[英]In Python, how to initialize a class attribute from the return value of a class method?

想象一下,我們有這個課程:

class Custom:
    @classmethod
    def get_choices(cls):
        # use cls attributes to return a list

    mapping = {"key": ... }

我想將get_choices()返回的值與key相關聯。 應該使用什么代碼而不是占位符...


編輯:我想保持與上下文無關的問題(在我看來,這個要求很常見,但我可能有偏見)。 正如評論中所建議的那樣,我將提供更多細節,因為我們似乎共同關注“最簡單的代碼”:

我正在開發一個Django應用程序,我希望使用它們來保持Model的值的枚舉 在我看來,像一個自然的解決方案是創建一個enumeration.py模塊,然后我可以為每個枚舉定義一個class (該類至少有一個類方法來生成值集合)。 這是示例中的get_choices()

現在,由於業務邏輯,我需要將這些選擇映射到密鑰。 這個映射在邏輯上耦合到枚舉,在同一個類中保持它們在一起似乎是一個很好的結構(給客戶端代碼統一和顯式訪問,以類名為前綴)。

您無法在類定義中執行此操作,因為尚未創建類對象。 在課程定義之后,你絕對可以做到這樣的事情 -

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

雖然推薦的方法是使用元類。

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

話雖如此,這是一個面向對象的問題解決方案。 您可以使用某些函數來生成選擇,從而結束使用元類的需要。

編輯問題: -

在這種情況下,我認為您應該按照自己的建議維護一個名為“choices.py”的文件,並在映射中使用它們,而不是使用get_choices類方法。 如果你想做的只是商店選擇,你不需要為每個模型不必要地創建類。 只需使用dicts和常量。

如果你的類需要動態生成,比如db,那么你需要創建單獨的模型來存儲選擇。

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
     }

這只是一個原始設計,可能需要進行很多改進,但在這些方面有所改進。

如果您需要運行的邏輯是微不足道的,那么只需在類之后直接放置邏輯:

class Custom1:
    value = 1
    @classmethod
    def get_choices(cls):
        return [cls.value]
Custom1.mapping = {"key": Custom1.get_choices()}

如果邏輯更復雜,特別是如果需要多個類,則裝飾器可能很有用。 例如

def add_mapping_choices(cls):
    cls.mapping = {"key": cls.get_choices()}
    return cls

@add_mapping_choices
class Custom2:
    value = 2
    @classmethod
    def get_choices(cls):
        return [cls.value]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM