【发布时间】:2020-07-26 14:25:35
【问题描述】:
在 Python 3.6+ 中使用 type() 时出现奇怪的行为。我正在使用它来动态包装来自外部库的所有类,并且在调用self.__dict__ 时出现错误。考虑以下示例:
class A(object):
def __init__(self):
print(self.__dict__)
class B(A):
def __init__(self):
super(self.__class__, self).__init__()
B() # this works
但是当我使用type 做同样的事情时,我得到了这个奇怪的错误:
class A(object):
def __init__(self):
print(self.__dict__)
class B(object):
def __init__(self):
super(self.__class__, self).__init__()
# C is a class which is B that inherits from A
C = type('C', (A,), B.__dict__.copy())
C()
# TypeError: descriptor '__dict__' for 'B' objects doesn't apply to 'C' object
如何使用type() 解决此问题?
[TLDR:@fritzo 的回答修复了错误,但这种设计引入了其他继承问题。 @juanpa.arrivillaga 接受的答案提供了更好的解决方法]
【问题讨论】:
-
不同的问题,但不要将
self.__class__或type(self)传递给super- it breaks as soon as you create a grandchild class。 -
我在非
__init__方法中需要它,否则我会得到TypeError: super(type, obj): obj must be an instance or subtype of type。 -
确实发生了该错误。不过,孙辈是为工作而设计的,而您所做的却不是。你所做的与
super不兼容,并且在很多其他情况下都会中断,而不仅仅是super或__dict__。你真的应该重新设计你的包装器;如果你不这样做,问题就会不断堆积,尤其是在外部库发生变化时。 -
根据程序其余部分的上下文,正确的解决方案可能是给您的
C一个B实例作为属性,或者使A混合从A和B多重继承。 -
所以我尝试使用 mixins,但无法获得我想要的功能。假设我有一个来自类 C(B, A) 的方法
foo(),其中 B 是我的 mixin,A 是外部类。在foo()中,我想检查一个属性是否存在并调用B.foo否则调用A.foo。但是在 B 中,我无法访问 A 的类(和方法)。这对于一个类来说很简单,只需在没有type的情况下将其写出来,但我想以编程方式为所有类执行此操作。这个怎么写?
标签: python python-3.x oop inheritance