可以通过子类或动态属性修改Python父类吗?

时间:2018-10-01 16:04:08

标签: python

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

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

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

这就是我想要做的:

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对象中。

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

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”变量,就像属性一样。但是,我不想每次都向databag类添加新函数,否则该类最终会变得非常大。

1 个答案:

答案 0 :(得分:0)

我可以使用以下方法获得类似的结果。虽然我想提出一个建议来使它起作用。我只是阅读了此链接上发布的帮助:

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