【问题标题】:Iteratively create subclass and store objects as class attribute迭代地创建子类并将对象存储为类属性
【发布时间】:2020-05-25 14:36:58
【问题描述】:

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

MyClass.myresults实际上是一个具有不同属性的类本身(例如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

我想创建一个单独的类 (Results),它在每次迭代时都会创建一个子类 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

非常欢迎提出不同方法的建议,我对课程很陌生,我不确定这是否是一种可接受的方法,或者我是否在做一些糟糕的事情(笨重、内存效率低下或其他)。

【问题讨论】:

    标签: python class subclass


    【解决方案1】:

    所以我用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))
    
    

    【讨论】:

      【解决方案2】:

      使用这种方法有两个问题,第一个是,Result类(单独的类)只存储你的类MyClass的修改值,我的意思是,他们应该是同一个班级。

      第二个问题是内存效率,你创建了两次相同的对象来存储实际值和每次迭代的修改值。

      建议的方法是在 python 中使用 hashmapdictionary。使用 dictionary 您可以非常高效地存储修改对象的副本,并且无需创建另一个类。

      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
      

      【讨论】:

      • 您好,感谢您的回答。然后如何调用每个存储的类对象的属性?使用您的示例,调用:superObject.scenarios_result[iter] 将返回一个类对象。我怎么打电话,例如:superObject.scenarios_result[iter].MyAttribute?
      • 不客气。是的,为了访问您的类属性(复制对象),您使用键(本例中为 iter)索引字典。
      猜你喜欢
      • 2022-10-14
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多