python 3.2 plugin factory: instantiation from class/metaclass
我正在从这里的信息中搜索:子类中没有调用元类
我的问题是无法使用这个类注册表创建对象的实例。如果我使用"常规"构造方法,那么它似乎可以正确地实例化对象;但是当我尝试使用与注册表关联的类对象时,我会得到一个错误,即传递的参数数量不正确。(似乎在调用元类new而不是我的构造函数…??)
我不清楚它为什么会失败,因为我认为我应该能够使用"可调用"语法从类对象创建实例。
似乎我要把元类放到注册表中,而不是类本身?但在新的调用中,我看不到访问类本身的简单方法。
下面是我的代码示例,它未能实例化变量"d":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | registry = [] # list of subclasses class PluginMetaclass(type): def __new__(cls, name, bases, attrs): print(cls) print(name) registry.append((name, cls)) return super(PluginMetaclass, cls).__new__(cls, name, bases, attrs) class Plugin(metaclass=PluginMetaclass): def __init__(self, stuff): self.stuff = stuff # in your plugin modules class SpamPlugin(Plugin): def __init__(self, stuff): self.stuff = stuff class BaconPlugin(Plugin): def __init__(self, stuff): self.stuff = stuff c = SpamPlugin(0) b = BaconPlugin(0) mycls = registry[1][1] d = mycls(0) |
谢谢你的帮助。
我认为您遇到的问题是,传递给元类构造函数的
这个修改后的版本在3.2版上对我有效:
1 2 3 4 5 6 7 8 | class PluginMetaclass(type): def __new__(cls, name, bases, attrs): print("Called metaclass: %r" % cls) print("Creating class with name: %r" % name) newclass = super(PluginMetaclass, cls).__new__(cls, name, bases, attrs) print("Registering class: %r" % newclass) registry.append((name, newclass)) return newclass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | >>> registry = [] >>> >>> class Plugin(metaclass=PluginMetaclass): ... def __init__(self, stuff): ... self.stuff = stuff ... Called metaclass: <class '__main__.PluginMetaclass'> Creating class with name: 'Plugin' Registering class: <class '__main__.Plugin'> >>> class SpamPlugin(Plugin): ... def __init__(self, stuff): ... self.stuff = stuff ... Called metaclass: <class '__main__.PluginMetaclass'> Creating class with name: 'SpamPlugin' Registering class: <class '__main__.SpamPlugin'> >>> class BaconPlugin(Plugin): ... def __init__(self, stuff): ... self.stuff = stuff ... Called metaclass: <class '__main__.PluginMetaclass'> Creating class with name: 'BaconPlugin' Registering class: <class '__main__.BaconPlugin'> >>> c = SpamPlugin(0) >>> b = BaconPlugin(0) >>> mycls = registry[1][1] >>> d = mycls(0) >>> d <__main__.SpamPlugin object at 0x010478D0> >>> registry [('Plugin', <class '__main__.Plugin'>), ('SpamPlugin', <class '__main__.SpamPlugin'>), ('BaconPlugin', <class '__main__.BaconPlugin'>)] |
编辑:@drone115b还通过在