代码之家  ›  专栏  ›  技术社区  ›  hansaplast

python:多继承,在基类中添加

  •  3
  • hansaplast  · 技术社区  · 14 年前

    我要处理的是一个基本类 __add__() 想支持什么时候 __add__ 划分两个子类实例-即结果实例中两个子类的方法。

    import copy
    
    class Base(dict):
        def __init__(self, **data):
            self.update(data)
    
        def __add__(self, other):
            result = copy.deepcopy(self)
            result.update(other)
            # how do I now join the methods?
            return result
    
    class A(Base):
        def a(self):
            print "test a"
    
    class B(Base):
        def b(self):
            print "test b"
    
    
    if __name__ == '__main__':
        a = A(a=1, b=2)
        b = B(c=1)
        c = a + b
        c.b() # should work
        c.a() # should work
    

    编辑 :更具体地说:我有一门课 Hosts 持有 dict(host01=.., host02=..) (因此将 dict )-这提供了一些基本方法,例如 run_ssh_commmand_on_all_hosts()

    现在我有了一个子类 HostsLoadbalancer 有一些特殊的方法,比如 drain() 我要上一节课 HostsNagios 这包含了一些特定于Nagios的方法。

    我现在做的是:

    nagios_hosts = nagios.gethosts()
    lb_hosts = loadbalancer.gethosts()
    hosts = nagios_hosts + lb_hosts
    hosts.run_ssh_command_on_all_hosts('uname')
    hosts.drain() # method of HostsLoadbalancer - drains just the loadbalancer-hosts
    hosts.acknoledge_downtime() # method of NagiosHosts - does this just for the nagios hosts, is overlapping
    

    这个问题的最佳解决方案是什么?

    我想我可以“复制所有方法”——就像这样: 对于目录中的x(其他): setattr(自我,x,getattr(其他,x))

    我走对了吗?还是应该使用抽象基类?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Mike Axiak    14 年前

    import copy
    
    class Base(dict):
        global_class_cache = {}
    
        def __init__(self, **data):
            self.local_data = data
    
        def __add__(self, other):
            new_instance = self._new_type((type(self), type(other)))()
            new_instance.update(copy.deepcopy(self).__dict__)
            new_instance.update(copy.deepcopy(other).__dict__)
            return new_instance
    
        def _new_type(self, parents):
            parents = tuple(parents)
            if parents not in Base.global_class_cache:
                name = '_'.join(cls.__name__ for cls in parents)
                Base.global_class_cache[parents] = type(name, parents, {})
            return Base.global_class_cache[parents]
    
    class A(Base):
        def a(self):
            print "test a"
    
    class B(Base):
        def b(self):
            print "test b"
    
    
    if __name__ == '__main__':
        a = A(a=1, b=2)
        b = B(c=1)
        c = a + b
        c.b() # should work
        c.a() # should work
        print c.__class__.__name__
    

        2
  •  0
  •   Escualo    14 年前

    Base say_hola()

    class Base(object):
       def say_hola(self):
         print "hola"
    
    class C1(Base):
       def add(self, a, b):
          return a+b
    
    class C2(Base):
       def say_bonjour(self):
          return 'bon jour'
    

    C1 C2

    Mixin