即使没有覆盖所有抽象方法,动态加载的子类仍然可以实现

时间:2014-01-13 22:24:27

标签: python inheritance

设置:Python 3.3

我有一个名为SourceBase的基类,它定义了抽象方法和值:

import abc

class SourceBase(object):
    __metaclass__=abc.ABCMeta
    pluginid='undefined' #OVERRIDE THIS IN YOUR SUBCLASS. If you don't, the program will ignore your plugin.

    @abc.abstractmethod
    def get_images(self):
        '''This method should return a list of URLs.'''
        return

    @abc.abstractmethod
    def get_source_info(self):
        '''This method should return a list containing a human friendly name at index 0, and a human readable url describing the source for this repository.
        For example, the EarthPorn subreddit returns a list ['EarthPorn Subreddit', 'http://reddit.com/r/EarthPorn'].
        This is used to populate the treeview object with your source information.'''
        return

    @abc.abstractmethod
    def get_pluginid(self):
        '''This method should return a string that represents this plugins ID.
        The pluginid is used to make calls to this plugin when necessary. It should be unique as ids are in a shared pool,
        so make sure the id is unique. The id should remain the same even when updated as some settings with the pluginid 
        are persisted by the main application, and they will be lost if the id changes.
        '''
        return

这是我写的一些python插件的超类,它是这个的子类。它们在运行时动态加载,所有这些都可以工作,除了我向SourceBase添加了一个新的抽象方法,插件仍然加载。他们不应该,因为他们都没有我的新方法。 (我给它了@ abc.abstractmethod标记)。

我的google-fu并没有真正显示任何东西,所以我不知道为什么我仍然能够实现这些插件,即使超类认为它们是抽象的。

例如,在SourceBase中,我添加了:

@abc.abstractmethod
def get_dependencies(self):
    print('ERROR: THIS PLUGIN SHOULD NOT HAVE LOADED.')
    '''This method should return a list of package names. The host program will check if these packages are available.
    If they are not available, the plugin will be disabled, but the user will be able to elect to install these packages.'''
    return

我没有在我的插件中定义此方法,但我仍然在终端上获得此输出:

....
Screen Height:1080
Screen Width:1920
files:  ['bingIOTD.py', 'redditEP.py', 'redditLP.py', '__init__.py']
ERROR: THIS PLUGIN SHOULD NOT HAVE LOADED. <--abstract method

我不确定为什么忽略它,我错过了什么......?我之前使用非动态加载的普通类完成了它。任何帮助表示赞赏。我知道我可以做一个解决方法(做一个默认的返回,检查一下),但这似乎不是正确的方法。

如果您需要更多源代码,我的项目是在SourceForge here.

1 个答案:

答案 0 :(得分:2)

In Python3元类由

指定
class SourceBase(metaclass=abc.ABCMeta):

class SourceBase(object):
    __metaclass__=abc.ABCMeta

代码忽略了abstractmethod装饰器,因为就Python3而言,SourceBase只是一个标准类(type的实例),带有属性 name {{ 1}}而不是__metaclass__的实例。