自定义ABC类:__new__() 需要4个参数(给定1个)

1 投票
1 回答
1839 浏览
提问于 2025-04-17 16:14

我想做一个插件式的文件上传器,这个上传器可以把文件上传到不同的服务。它会从一个文件夹里加载所有的Python模块,然后根据要上传的服务来调用相应的模块。

我有一个简单的BaseHandler类,它是所有插件的抽象基类。

import abc

class BaseHandler():
   __metaclass__ = abc.ABCMeta

   @abc.abstractmethod
   def start(self,startString):
      return

我有一个简单的插件,它是从BaseHandler继承过来的。

from BaseHandler import BaseHandler

class Cloud(BaseHandler):
    def start(self,startString): 
        return

还有一段实际的代码,用来加载插件并调用它们。

import logging
import os
import sys
from BaseHandler import BaseHandler

all_plugins = {}

def load_plugins():
    plugin_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"Handlers")
    plugin_files = [x[:-3] for x in os.listdir(plugin_dir) if x.endswith(".py")]
    sys.path.insert(0,plugin_dir)
    for plugin in plugin_files:
        mod = __import__(plugin)
    logging.info('Plugins have been loaded from the directory '+plugin_dir)
    for plugin in BaseHandler.__subclasses__():
        logging.info('Plugin:'+plugin.__name__)    
    return BaseHandler.__subclasses__()

logging.basicConfig(level=logging.DEBUG)
loadedPlugins = load_plugins()

for plugin in loadedPlugins:
    all_plugins[plugin.__name__]= plugin.__class__
    handle = all_plugins[plugin.__name__]()

当我在脚本的最后一行尝试创建这个插件的实际对象时,

    handle = all_plugins[plugin.__name__]()

我遇到了一个错误:TypeError: __new__() takes exactly 4 arguments (1 given)

补充:我添加了完整的错误追踪信息。

Traceback (most recent call last):
   File "C:\TestCopy\Test.py", line 24, in <
module>
    handle = all_plugins[plugin.__name__]()
TypeError: __new__() takes exactly 4 arguments (1 given)

1 个回答

1

你现在注册的是 元类,而不是插件本身;

>>> BaseHandler()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class BaseHandler with abstract methods start

我觉得你是想保存插件本身:

all_plugins[plugin.__name__] = plugin

这里的 __class__ 属性指的是 BaseHandler 类;而 plugin 对象是类,不是实例。

撰写回答