我所问的可能看起来很奇怪,但这是一个例子:
我有课程' A'
class A:
a=1
其他我班级' B'
class B:
def __init__(self, obj):
self.obj = obj # obj is any object
现在我用:
first = A()
second = B(first)
isinstance(second, A)
我希望第3步是真的。即,无论B对象是什么,它都应该将对象类型的实例添加到对象中。
Python中是否可以这样?
答案 0 :(得分:2)
使用继承,是的:
class B(A):
def __init__(self, obj):
self.obj = obj # obj is any object
答案 1 :(得分:2)
2可能性
代替isinstance(second, A)
执行isinstance(second.obj, A)
第二......更糟糕的做法是做这样的事情:
class B:
def __init__(self, obj):
self.obj = obj # obj is any object
self.__class__ = obj.__class__
这是hackish,因为它基本上欺骗了解释器,认为实例是一个不同的类。那是isinstance(second, B)
将返回False
要回答下面提出的问题:解释器基本上就像second
是一个类A
,并且B
中的任何类别都没有定义。例如,如果你做了类似
class B:
b=2 #Won't be visible
def __init__(self, obj):
self.obj = obj # obj is any object
self.b2 = 5 #Instance variable will be visible
self.__class__ = obj.__class__
def someFunc(self): #Won't be visible
return 3
使用与上面用于初始化的相同代码,这是使用解释器的一些调用会发生的情况。通常,将删除任何类变量或方法,而是使用A
'a,但是将记住任何实例变量。因为这样做self.obj = obj
有点多余。基本上实例化B(obj)
将或多或少地返回与obj
相同的类的对象。虽然它不会调用obj
的{{1}},但为此您需要更多的伏都教/魔法(如果您只是感兴趣的话)。
__init__
答案 2 :(得分:2)
您当然可以覆盖__new__
并从type
而不是object
派生您的对象,从而有效地创建一个类工厂......
你最终做的非常类似于:
b = type('B', (A,), {'obj': A()})
它生成一个从A派生的class B
,包含该A()的实例 - 因为这是一个函数,你可以根据你想要的任何原因传递你想要的任何东西。
答案 3 :(得分:1)
我很想提出这种情况极不可能是一个好主意,即使它可以以非黑客的方式存在。 (编辑:乔恩克莱门茨的建议让我感到最好/最少的hackish方式,但我仍然建议我的其余部分是相关的。)我还有进一步的危险,这表明这是混淆/混淆与这是一个“是一个”的关系应该是一个“有一个”的关系。除非有关OP正在努力实现的更多细节,否则无法确切知道。
无论如何,有人(Kent Beck,我认为)曾经说过(我记得这句话),继承会在代码体之间产生非常强大的耦合,伴随着维护和增强方面的困难,因此继承应该在你的一袋技巧,不应轻易使用。换句话说:在可能的情况下,首选组合(或聚合)而不是继承。