Metaclass报错:TypeError: Config_setup.__init__()参数个数不符求解决
问题:TypeError: Config_setup.init() takes from 1 to 2 positional arguments but 4 were given
错误信息
in <module> class Config(metaclass=Config_setup): TypeError: Config_setup.__init__() takes from 1 to 2 positional arguments but 4 were given
问题描述
运行代码时出现上述错误,不清楚解决方法,求思路。以下是来自“Crowd_flow_prediction”的代码:
from __future__ import print_function import os import platform class Config_setup(object): """docstring for Config""" _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Config_setup, cls).__call__(*args, **kwargs) else: cls._instances[cls].__init__(*args, **kwargs) return cls._instances[cls] def __init__(self, DATAPATH=None): super(Config, self).__init__() if DATAPATH is None: DATAPATH = os.environ.get('DATAPATH') if DATAPATH is None: if platform.system() == "Windows" or platform.system() == "Linux": # DATAPATH = "D:/data/traffic_flow" # elif platform.system() == "Linux": DATAPATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../..', 'data') else: print("Unsupported/Unknown OS: ", platform.system, "please set DATAPATH") self.DATAPATH = DATAPATH class Config(metaclass=Config_setup): pass
错误原因
- 元类定义不合法:
Config_setup被指定为Config的元类,但它继承自object而非Python元类的基类type。元类的__init__方法默认需要接收4个参数(元类本身、目标类名、目标类父组、目标类命名空间),原代码只定义了2个参数,导致参数不匹配报错。 - 代码结构混乱:配置类的初始化逻辑被错误写在元类中,且
super(Config, self).__init__()调用时Config类尚未定义,会引发额外错误。 - 逻辑细节错误:判断操作系统的代码注释混乱,且
platform.system未加括号调用,无法正确获取系统名称。
解决思路与修正代码
方案一:修正元类实现单例(贴合原代码意图)
将Config_setup改为合法元类,把配置初始化逻辑移到Config类中:
from __future__ import print_function import os import platform class Config_setup(type): """用元类实现单例模式""" _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Config_setup, cls).__call__(*args, **kwargs) else: cls._instances[cls].__init__(*args, **kwargs) return cls._instances[cls] class Config(metaclass=Config_setup): def __init__(self, DATAPATH=None): if DATAPATH is None: DATAPATH = os.environ.get('DATAPATH') if DATAPATH is None: if platform.system() in ("Windows", "Linux"): DATAPATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../..', 'data') else: print(f"Unsupported/Unknown OS: {platform.system()}, please set DATAPATH") self.DATAPATH = DATAPATH
方案二:用装饰器实现单例(更适合新手)
如果不想用元类,装饰器方式更直观易懂:
from __future__ import print_function import os import platform def singleton(cls): instances = {} def wrapper(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) else: instances[cls].__init__(*args, **kwargs) return instances[cls] return wrapper @singleton class Config: def __init__(self, DATAPATH=None): if DATAPATH is None: DATAPATH = os.environ.get('DATAPATH') if DATAPATH is None: if platform.system() in ("Windows", "Linux"): DATAPATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../..', 'data') else: print(f"Unsupported/Unknown OS: {platform.system()}, please set DATAPATH") self.DATAPATH = DATAPATH
关键修正点说明
- 元类必须继承
type才能被Python识别为合法元类 - 将配置初始化逻辑移到
Config类中,避免未定义类的引用错误 - 修复
platform.system()的调用方式,补充括号使其执行方法获取系统名称 - 合并操作系统判断逻辑,简化冗余代码
内容的提问来源于stack exchange,提问作者samira
相关产品推荐
相关产品推荐

