Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 描述符'__dict';对于对象不';无法使用类型()应用于对象_Python_Python 3.x_Oop_Inheritance - Fatal编程技术网

Python 描述符'__dict';对于对象不';无法使用类型()应用于对象

Python 描述符'__dict';对于对象不';无法使用类型()应用于对象,python,python-3.x,oop,inheritance,Python,Python 3.x,Oop,Inheritance,在Python3.6+中使用type()时,我的行为很奇怪。我正在使用它动态包装外部库中的所有类,在调用self.\uu dict\uu时出错。考虑下面的例子: class A(object): def __init__(self): print(self.__dict__) class B(A): def __init__(self): super(self.__class__, self).__init__() B() # this wor

在Python3.6+中使用
type()
时,我的行为很奇怪。我正在使用它动态包装外部库中的所有类,在调用
self.\uu dict\uu
时出错。考虑下面的例子:

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接受的答案提供了一个更好的解决方法]

根据您关于希望动态执行此操作的评论,您可以使用
super
,但您必须了解其工作原理,
super
为您提供了方法解析顺序中的下一个方法,因此您确实可以从mixin访问
A
中的方法,但您必须正确使用
super
:因此类似的方法可以工作:

In [1]: class Mixin:
   ...:     def foo(self):
   ...:         if hasattr(self, 'whatever'):
   ...:             print("doing Mixin.foo stuff")
   ...:         else:
   ...:             return super().foo()
   ...:

In [2]: class A:
   ...:     def foo(self):
   ...:         print("doing A.foo stuff")
   ...:

In [3]: class C(Mixin, A):
   ...:     pass
   ...:

In [4]: c = C()

In [5]: c.foo()
doing A.foo stuff

In [6]: c.whatever = 42

In [7]: c.foo()
doing Mixin.foo stuff
然而,我不确定这是否值得推荐。但这是可能的

请注意,所谓动态,我指的是这样的工作方式:

In [9]: class Mixin:
   ...:     def foo(self):
   ...:         if hasattr(self, 'whatever'):
   ...:             print("doing Mixin.foo stuff")
   ...:         else:
   ...:             return super().foo()
   ...: class A:
   ...:     pass
   ...:
   ...: class B:
   ...:     def foo(self):
   ...:         print("doing B.foo stuff")
   ...:
   ...: class C(Mixin, A, B):
   ...:     pass
   ...:

In [10]: c = C()

In [11]: c.foo()
doing B.foo stuff

In [12]: c.whatever = 42

In [13]: c.foo()
doing Mixin.foo stuff

不同的问题,但永远不要传递给
self.\uu类\uuuuuuu
type(self)
super
。我需要在非
初始化\uuuuuu
方法中使用它,否则我会得到
类型错误:super(type,obj):obj必须是类型的实例或子类型
。这个错误确实发生了。然而,孙辈是为工作而设计的,而你所做的却不是。您所做的操作与
super
不兼容,并且在许多其他情况下都会中断,而不仅仅是
super
\uuuuuuuuu dict
。你真的应该重新设计你的包装;如果不这样做,问题将不断堆积,特别是当外部库发生变化时。根据程序其余部分的上下文,正确的解决方案可能是将
C
a
B
实例作为属性,或者使
A
混合并从
A
B
继承多个。因此,我尝试使用mixin,但无法获得所需的功能。假设我有一个来自类C(B,a)的方法
foo()
,其中B是我的mixin,a是一个外部类。在
foo()
中,我想检查属性是否存在并调用
B.foo
否则调用
A.foo
。但是在B中,我没有访问A的类(和方法)的权限。对于一个类来说,这是很简单的,不需要
类型
,但我希望以编程的方式对所有类都这样做。我该怎么写呢?谢谢你的回复!我正在加载一堆不同的
a
s,所以通过编程(AFAIK)实现这一点的唯一方法是使用
C=type('C',(Mixin,a),Mixin.\uu dict\uuuu.copy())
,这与我在OP中的内容有关。但是我在
super().foo()
中得到类型错误,上面的注释中有类型错误。我可以用
super(self.\uuu class\uuuuu,self)
来解决这个问题,但是根据我们上面的对话,这是不可取的。@luxon如果你能完整地描述一下你所面临的实际问题,那会有帮助的。这是一个类的例子,是的,我的意思是
C=type('C',(Mixin,a),{})
。我在前面调用
super()
时遇到了一个问题,但我相信这个解决方案是可行的。谢谢我将编辑并接受您的回复;我尽量避免编辑OP,因为其他人可能只是想用不同的问题调试错误消息。让我重申一下我的高级问题。有一个外部库,其中包含一组共享公共父类的类。我想重写每个类中的一些方法,以便在满足条件时执行自定义逻辑,否则使用原始逻辑。在这个上游库中可以添加新的类,所以我想动态地这样做(在您的示例中,假设有{A_1,A_2,…A_n},其中n是类的数量)@luxon,然后您可以使用一个类定义语句<代码>对于类列表中的cls:类X(混合,cls):通过