迭代创建 subclass 并将对象存储为 class 属性

Iteratively create subclass and store objects as class attribute

我有一个 class 可以进行一些复杂的计算并生成一些结果 MyClass.myresults

MyClass.myresults 实际上是一个 class 本身,具有不同的属性(例如 MyClass.myresults.mydf1MyClass.myresults.mydf2.

现在,我需要 运行 MyClass 迭代地遵循场景列表(scenarios=[1,2,[2,4], 5]

这是一个简单的循环:

    for iter in scenarios:
        iter = [iter] if isinstance(iter, int) else iter
        myclass = MyClass() #Initialize MyClass
        myclass.DoStuff(someInput) #Do stuff and get results
        results.StoreScenario(myclass.myresults, iter)

并在每次迭代结束时存储 MyClass.myresults

我想创建一个单独的 class (Results),它在每次迭代时创建一个子class scenario_1, scenario_2, scenario_2_4 并存储在其中 MyClass.myresults .

class Results:
    # no initialization, is an empty container to which I would like to add attributes iteratively
    class StoreScenario:
        def __init__(self, myresults, iter):
            self.'scenario_'.join(str(iter)) = myresults #just a guess, I am assuming this is wrong

非常欢迎关于不同方法的建议,我对 classes 很陌生,我不确定这是否是一种可接受的方法,或者我是否在做一些糟糕的事情(笨拙、内存效率低下,或者否则)。

使用这种方法有两个问题,第一个是,Result class(单独的 class)只存储修改后的值 class MyClass,我的意思是,它们应该是一样的class。

第二个问题是内存效率,您创建同一个对象两次,用于在每次迭代时存储实际值和修改后的值。

建议的方法是在 python 中使用 hashmapdictionary。使用 字典 您可以非常有效地存储修改对象的副本,而无需创建另一个 class。

class MyClass:
  def __init__(self):
    # some attributes ...
    self.scenarios_result = {}

superObject = MyClass()

for iter in scenarios:

    iter = [iter] if isinstance(iter, int) else iter

    myclass = MyClass() #Initialize MyClass
    myclass.DoStuff(someInput) #Do stuff and get results

    # results.StoreScenario(myclass.myresults, iter)

    superObject.scenarios_result[iter] = myclass

所以我用setattr解决了它:

class Results:

    def __init__(self):
        self.scenario_results= type('ScenarioResults', (), {}) # create an empty object


    def store_scenario(self, data, scenarios):
        scenario_key = 'scenario_' + '_'.join(str(x) for x in scenarios)
        setattr(self.simulation_results, scenario_key, 
                subclass_store_scenario(data))

class subclass_store_scenario:
    def __init__(self, data):

        self.some_stuff = data.result1.__dict__
        self.other_stuff = data.result2.__dict__

这让我可以像这样调用:

results.scenario_results.scenario_1.some_stuff.something
results.scenario_results.scenario_1.some_stuff.something_else

这对我来说是必要的,因为我需要计算其他度量、摘要或特定场景,然后我可以再次使用迭代分配它们 setattr:

    def construct_measures(self, some_data, configuration):
        for scenario in self.scenario_results: 
            #scenario is a reference to the self.scenario_results class. 
            #we can simply add attributes to it
            setattr(scenario , 'some_measure',
                    self.computeSomething(
                            some_data.input1, some_data.input2))