gpt4 book ai didi

Python 元类冲突/类型错误

转载 作者:行者123 更新时间:2023-11-28 20:39:22 27 4
gpt4 key购买 nike

我正在调试 python 脚本(python 不是我的首选语言),这是我第一次在 python 中使用元类。运行代码时出现元类冲突错误,如下所示。

TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

在尝试解决它时,我注释掉了 MySQLMSoftware 中的元类声明,认为它是多余的,因为它继承自具有相同元类声明的类,但这导致:

TypeError: Error when calling the metaclass bases
module.__init__() takes at most 2 arguments (3 given)

任何见解、指导或方向将不胜感激。我一直在阅读有关 python 的元类实现的信息,但到目前为止还没有出现这个问题。

MSoftware.py

from abc import ABCMeta, abstractmethod

class MSoftware(object) :
__metaclass__ = ABCMeta

def __init__(self,name,spark=None,mysql=None):
self.name = name
...

MySQLMSoftware.py

from mouse import Mouse, MSoftware
from abc import ABCMeta, abstractmethod

class MySQLMSoftware(MSoftware): # Traceback always goes here
__metaclass__ = ABCMeta

MAX_ROWS = 30000000

def __init__(self,name,years,spark=None,mysql=None):
MSoftware.__init__(self,name,spark,mysql)
self.years = years
...

TTime.py

from mouse.Mouse import Mouse
from mouse.MySQLMSoftware import MySQLMSoftware

class TTime(MySQLMSoftware) :

DATABASE = "Database"
NAME = "table"
YEARS = [2014,2016]

def __init__(self,spark=None,mysql=None):
MySQLMSoftware.__init__(self,TTime.NAME,TTime.YEARS,spark,mysql)
...

主.py

import sys
from mouse.Mouse import Mouse
from mouse.TTime import TTime

...

最佳答案

问题是在选择元类时,python 会选择继承最多的版本。但是,您有两个相互冲突的元类(ABCMeta 和任何 MSoftware 拥有的)。

我认为 python3.x docs在这方面比 python2.x 文档稍微更正确:

The appropriate metaclass for a class definition is determined as follows:

  • if no bases and no explicit metaclass are given, then type() is used
  • if an explicit metaclass is given and it is not an instance of type(), > then it is used directly as the metaclass
  • if an instance of type() is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used

一个解决方案是创建一个新的元类,它是两者的混合:

class NewMeta(type(MSoftware), ABCMeta):
pass

在这种情况下,由于所有的元类都是MSoftware 的元类的“实例”,NewMeta 将被选中,因为它是最派生的元类,并且应该工作(前提是 MSoftware 的元类可以用于协作多重继承)。

这是一个动态创建 NewMeta 的示例,以通过一些虚拟类解决此问题:

class Meta1(type):
pass

class Meta2(type):
pass

class Class1(object):
__metaclass__ = Meta1


# TypeError!
# class Class2(Class1):
# __metaclass__ = Meta2

class Class2(Class1):
__metaclass__ = type('Class2Meta', (type(Class1), Meta2), {})

关于Python 元类冲突/类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38403795/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com