在python中使用类实例作为父类

时间:2018-05-11 13:09:39

标签: python

我正在努力更好地理解python类系统。这个问题只是为了满足我的好奇心。

是否可以以某种方式使用类实例作为另一个类的父类。到目前为止,我试图做的是

public class EntityExample
{
    /// <summary>
    /// Returns a Dictionary of estimated future states after "doing" the IAction parameter
    /// </summary>
    Dictionary<IEntity, Probability> EstimatePossibleOutcomeSpectrum(IAction action)
    {
        action.[Some method or a Action<Entity> call](this);
    }
    /// <summary>
    /// "do" the Action paramater
    /// </summary>
    void Do(IAction action)
    {
        action.[Some method or a Action<Entity> call](this);
    }
}

并出现以下错误:class A: pass a = A() class B(a): pass

TypeError: object() takes no parameters

并且它会出现此错误class Meta(type): pass class A: pass a = A() class B(a, metaclass=Meta): pass

我想知道,是否有可能以某种方式将所有类实例方法代理到元类,因此我的实例将表现为类

4 个答案:

答案 0 :(得分:1)

  

是否可以以某种方式使用类实例作为另一个类的父类

嗯,实际上情况总是如此,因为类是ARE实例(它们的元类)。但是,你想要用作父类的实例的类(是的,重读三次......)必须表现得好像它是一个真正的元类 - 它可以迅速变得不切实际。

  

我想知道,是否有可能以某种方式将所有类实例方法代理到元类,因此我的实例将表现为类

确实可能有某种方式(覆盖__getattr__()__getattribute__()),但是细节中存在魔鬼,而且当你制作这种rube goldberg装置时,机会很可能是“工作 - 有严重限制和角落的情况“,你会怀疑这是否真的值得痛苦。

请注意,在Python中,OTHO组合/委托和动态(运行时)创建/修改类都非常容易,因此我很难想象(ab)使用实例作为父类可以更好地解决这个问题。

答案 1 :(得分:0)

编辑:

好的,所以如果你可以控制基类(使用元类或__init_subclass__(python 3.6或更高版本)),就可以破解

class A:
    x = 1
    def __init_subclass__(cls, inst, **kwargs):
        super().__init_subclass__(**kwargs)
        for k, v in vars(inst).items():
            if k not in dir(cls):  # i.e. don't override but remove if you want to
                setattr(cls, k, v)

a = A()
a.y = 2   

class B(A, inst=a):
    pass

B.x # --> 1
B.y # --> 2

你的第二个例子就是在正确的轨道上。是的,这是可能的。

class Meta(type): pass
class A(metaclass=Meta): pass
class B(A): pass

issubclass(B, A) # --> True
isinstance(B, Meta) # --> True

多数民众赞成因为AMeta的一个实例(这就是元类的意思,一个实例也是类的类)。因此BMeta的实例的子类。

所以是的,你可以设置例如

class Meta(type):
    def __init__(cls, *args, **kwargs):
         cls.x = 1
         super().__init__(cls, *args, **kwargs)

class A(Meta):
    def __init__(self):
         self.y = 2

A.x  # 1 (acts as an instance of Meta)
a = A()
a.y  # 2 (acts as an instance of A)
a.x  # AttributeError (does not act as an instance of Meta)

答案 2 :(得分:0)

每个实例都有__class__属性,该属性引用基础class结构。

了解这一点,您实际上可以执行以下操作:

class A(object):
   def foo(self):
      return 'hello'

a = A()

class B(a.__class__):
    pass

b = B()
print(b.foo()) # Prints 'hello'

或者,您也可以使用type

class B(type(a)):
    pass

b = B()
print(b.foo()) # Prints 'hello'

答案 3 :(得分:0)

您的实例必须是type才能在继承链中使用。例如:

class A(type):
    pass

a = A(str)  # you need to pass the type's `type` to the construcor

class B(a):
    pass

话虽如此,如果没有我能想到的实际应用,那就很少 - 或者说你用这种方式实现的任何东西都会更容易,更多 Pythonic 通过正常实现继承和元类。