将容器类属性链接到包含的类属性

时间:2017-10-04 07:46:48

标签: python oop facade getattr

我正在研究一组太阳能电池板(系统/容器)。该集群的属性几乎一对一地链接到元素的属性 - 面板(子系统/包含) - 通过每个集群的元素数量。例如。集群的能源生产只是集群中面板的数量乘以单集群的生产。相同的成本,重量等。我的问题是如何将容器类链接到包含的类。

让我用一个天真的例子方法来说明:

class PanelA(BasePanel):
    ... _x,_y,_area,_production,etc.

    @property
    def production(self):
        # J/panel/s
        return self._area * self._efficiency

    ... and 20 similar properties

    @property
    def _technical_detail

class PanelB(BasePanel):
    .... similar

class PanelCluster():
    ....        
    self.panel = PanelA()
    self.density = 100 # panels/ha

    @property
    def production(self):
        # J/ha/h

        uc = 60*60 # unit conversion
        rho = self.density
        production_single_panel = self.panel.production

        return uc*rho*production_single_panel

    ... and e.g. 20 similar constructions

注意,在这种天真的方法中,人们会写出例如20种这样的方法似乎不符合这种DRY原则。

什么是更好的选择? (Ab)使用 getattr

例如?

class Panel():
     unit = {'production':'J/panel/s'}

class PanelCluster():
     panel = Panel()

     def __getattr__(self,key):

        if self.panel.__hasattr__(key)
            panel_unit = self.panel.unit[key]

            if '/panel/s' in panel_unit:

                uc = 60*60 # unit conversion
                rho = self.density
                value_per_panel = getattr(self.panel,key)

                return uc*rho*value_per_panel
            else:
                return getattr(self.panel,key)

这似乎已经更具“程序化”,但可能是天真的 - 再次。所以我想知道有哪些选择和优点/缺点?

1 个答案:

答案 0 :(得分:1)

您的代码存在许多Python问题,例如:

  • yield表示Python中特定的内容,可能不是一个好的标识符

它的拼写:

  • hasattr(self.panel.unit,key)
  • getattr(self.panel,key)

除此之外,您可能正在寻找涉及继承的解决方案。也许PanelPanelCluster都需要从PanelFunction类继承?

class PanelFunctions(object):
    @property
    def Yield(...):
        ...

class Panel(PanelFunctions):
    ..

class PanelCluster(PanelFunctions):
    ..

我会将属性保留为separte定义,因为您需要为所有属性编写单元测试(并且通过这种方式更容易确定覆盖率)。