【问题标题】:Python: Construct class (and variable names) through a function?Python:通过函数构造类(和变量名)?
【发布时间】:2021-03-25 13:06:20
【问题描述】:

我最近开始使用 Python 的类,因为我需要通过使用 OTree(用于在线实验的 Python 框架)来使用它。

在一个文件中,我使用类定义了我想要创建的页面。所以本质上,在 OTree 系统中,每个类对应一个新页面。问题是,所有的页面(so classes)基本上都是一样的,只是有些两个参数的例外,如下代码所示:

class Task1(Page):
    form_model = 'player'
    form_fields = ['Envie_WordsList_Toy']
    def is_displayed(self):
        return self.round_number == self.participant.vars['task_rounds'][1]
    def vars_for_template(player):
        WordsList_Toy= Constants.WordsList_Toy.copy()
        random.shuffle(WordsList_Toy)
        return dict(
            WordsList_Toy=WordsList_Toy
        )
    @staticmethod
    def live_method(player, data):
        player.WTP_WordsList_Toy = int(data)
    def before_next_page(self):
        self.participant.vars['Envie_WordsList_Toy'] = self.player.Envie_WordsList_Toy
        self.participant.vars['WTP_WordsList_Toy'] = self.player.WTP_WordsList_Toy

所以在这里,唯一会改变的是类的名称,以及整个代码中使用的变量WordsList_ 的后缀,即Toy

天真地,我试图做的是定义一个接受这两个参数的函数,例如:

def page_creation(Task_Number,name_type):
    class Task+str(Task_Number)(Page):
        form_model = 'player'
        form_fields = ['Envie_WordsList_'+str(name_type)]

        def is_displayed(self):
            return self.round_number == self.participant.vars['task_rounds'][1]

        def vars_for_template(player):
            WordsList_+str(name_type) = Constants.WordsList+str(name_type).copy()
            random.shuffle(WordsList_+str(name_type))
            return dict(
                WordsList_+str(name_type)=WordsList_+str(name_type)
            )

        @staticmethod
        def live_method(player, data):
            player.WTP_WordsList_+str(name_type) = int(data)

        def before_next_page(self):
            self.participant.vars['Envie_WordsList_+str(name_type)'] = self.player.Envie_WordsList_+str(name_type)
            self.participant.vars['WTP_WordsList_+str(name_type)'] = self.player.WTP_WordsList_+str(name_type)

显然,它不起作用,因为我觉得不可能以这种方式构造变量(或类标识符)。几周前我才开始真正研究 Python,所以它的某些方面可能仍然让我无法理解。你能帮我解决这个问题吗?谢谢。

【问题讨论】:

    标签: python class otree


    【解决方案1】:

    您可以使用type 构造函数生成动态类:

    
    MyClass = type("MyClass", (BaseClass1, BaseClass2), {"attr1": "value1", ...})
    

    因此,根据您的情况,这将是:

    cls = type(f"Task{TaskNumber}", (Page, ), {"form_fields": [f"Envive_WordList_{name_type}"], ...})
    

    请注意,您仍然必须构造您的常用方法,如__init__is_displayed 等,作为类工厂的内部函数:

    def class_factory(*args, **kwargs):
        ...
        def is_displayed(self):
            return self.round_number == self.participant.vars['task_rounds']
    
        def vars_for_template(player):
            ...
    
        # Classmethod wrapping is done below
        def live_method(player, data):
            ...
        cls = type(..., {
            "is_displayed": is_displayed, 
            "vars_for_template": vars_for_template,
            "live_method": classmethod(live_method),
            ...,
        }
    
    
    

    @classmethod 可以用作函数 - {"live_method": classmethod(my_method)}

    【讨论】:

    • 感谢您的回答。但是,我仍然在努力在类范围内定义函数的过程。例如,对于isdisplayed,我在哪里定义return self.round_number == self.participant.vars['task_rounds'][1]
    猜你喜欢
    • 2011-08-08
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    相关资源
    最近更新 更多