首页 > 解决方案 > 子类或动态属性可修改的Python父类?

问题描述

所以我什至不确定我想做的事情是否可行,但我想我会问并找出答案。

我想通过 python 构建一个厨师“数据包”。这几乎只是一个 python 字典。封装在 Databag 类中的此数据包还需要执行其他操作。

现在对于问题的实质......我想向这个字典添加键/值,但需要以一种易于扩展的方式构建它。注意:theautodict是一个类,因此您可以使用点符号构建字典。

这是我正在尝试做的事情:

databag = Databag(
  LogGroup=Sub("xva-${environment}-${uniqueid}-mygroup"),
  RunList=[
    "mysetup::default",
    "consul::client"
  ]
)
databag.Consul()  <-- Trying to add consul key/values to databag
print(databag.to_dict())
print(databag.to_string_list())

所以你可以看到我如何将“consul”键值添加到已经存在的数据包对象中。

这是类定义。我知道这是错误的,这就是为什么我来这里看看这是否可能。

Databag Class

class Databag(object):

def __init__(self,uniqueid=Ref("uniqueid"),environment=Ref("environment"),LogGroup=None,RunList=[]):
    self.databag = autodict()
    self.databag.uniqueid = uniqueid
    self.databag.environment = environment
    self.databag.log.group = LogGroup
    self.runlist=RunList

def to_string_list(self):
    return self.convert_databag_to_string(self.databag)

def to_dict(self):
    return self.databag

def get_runlist(self):
    return self.convert_to_runlist_string(self.runlist)

Consul Class

class Consul(Databag):

  def __init__(self, LogGroup=None):
      if LogGroup == None:
          Databag.consul.log.group = Databag.log.group
      else:
          Databag.consul.log.group = LogGroup

如您所见,Consul该类应该访问该类的databag字典Databag并添加“consul”变量,几乎就像一个属性。但是,我不想每次都向数据包类添加一个新函数,否则该类最终会变得非常非常大。

标签: python

解决方案


我能够使用以下方法获得类似的东西。尽管我愿意提出建议以使其发挥作用。我刚刚阅读了此链接上发布的帮助:

http://www.qtrac.eu/pyclassmulti.html

编辑:这种方法要容易得多:

注意:这使用与旧方法完全相同的实现。

consul.py

from classes.databag.utils import *

class Consul:
    def Consul(self, LogGroup=None):
        if LogGroup == None:
            self.databag.consul.log.group = self.databag.log.group
        else:
            self.databag.consul.log.group = LogGroup

databag.py

from classes.databag.utils import autodict
from classes.databag import consul

class Databag(consul.Consul):

    def __init__(self,uniqueid=Ref("uniqueid"),environment=Ref("environment"),LogGroup=None,RunList=[]):
        self.databag = autodict()
        self.databag.uniqueid = uniqueid
...
...

Folder Structure

/classes/
    databag/
        utils.py
        databag.py
        consul.py
testing.py

---- 旧方法 -----

How I implemented it

from classes.databag.databag import *

databag = Databag(
    LogGroup=Sub("xva-${environment}-${uniqueid}-traefik"),
    RunList=[
        "mysetup::default",
        "consul::client"
    ]
)
databag.Consul()

print(databag.to_dict())
print(databag.to_string_list())

lib.py

def add_methods_from(*modules):
    def decorator(Class):
       for module in modules:
           for method in getattr(module, "__methods__"):
               setattr(Class, method.__name__, method)
       return Class
return decorator

def register_method(methods):
    def register_method(method):
        methods.append(method)
        return method
    return register_method

databay.py

from classes.databag import lib, consul

@lib.add_methods_from(consul)
class Databag(object):

    def __init__(self,uniqueid=Ref("uniqueid"),environment=Ref("environment"),LogGroup=None,RunList=[]):
        self.databag = autodict()
        self.databag.uniqueid = uniqueid
    ....
    ....

consul.py

from classes.databag import lib

__methods__ = []
register_method = lib.register_method(__methods__)

@register_method
def Consul(self, LogGroup=None):
    if LogGroup == None:
        self.databag.consul.log.group = self.databag.log.group
    else:
        self.databag.consul.log.group = LogGroup

Folder Structure

/classes/
    /databag
        lib.py
        databag.py
        consul.py
        utils.py
/testing.py

推荐阅读