我正在努力更好地理解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
我想知道,是否有可能以某种方式将所有类实例方法代理到元类,因此我的实例将表现为类
答案 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
多数民众赞成因为A
是Meta
的一个实例(这就是元类的意思,一个实例也是类的类)。因此B
是Meta
的实例的子类。
所以是的,你可以设置例如
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 通过正常实现继承和元类。