Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 即使没有覆盖所有抽象方法,动态加载的子类仍然可以实例化_Python_Inheritance - Fatal编程技术网

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

Python 即使没有覆盖所有抽象方法,动态加载的子类仍然可以实例化,python,inheritance,Python,Inheritance,设置:Python3.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

设置:Python3.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标记)

我的GoogleFu没有显示任何东西,所以我不确定为什么我仍然可以实例化这些插件,尽管超类说它们是抽象的

例如,在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
。。。。
屏幕高度:1080
屏幕宽度:1920
文件:['bingIOTD.py','redditEP.py','redditLP.py','uuuu init.'uuuuuu.py']
错误:此插件不应加载 元类由指定

class SourceBase(metaclass=abc.ABCMeta):
不是


代码忽略了abstractmethod decorator,因为就Python3而言,
SourceBase
只是一个标准类(类型为
type
)的实例,其属性名为
\uuuuuuuuuuuuuuu
,而不是
abc的实例。ABCMeta

是否实例化了插件,或者它们只是用作类?它们是实例化的。我创建一个对象并将其存储在dict中。然后,当用户做某事时,我调用插件上的特定方法(单击“下载图像”按钮)。我将其保存在内存中,因为用户可能会再次单击按钮。在您的
bingIOTD
模块中,
SourceBase.\uuu模块\uu
打印什么?
sys.modules[SourceBase.\uuuuuuu module\uuuuuuu]。\uuuuuu文件\uuuuu
打印什么?可能是您没有导入更新的源代码。Sourcebase模块:EPDownloader.Sourcebase:::sourcesbase的sys.modules:[…]\FreshSet\EPDownloader\Sourcebase.py:::这些文件似乎是同一个文件。我只有一份此SourceBase的副本。现在它包含在工作区中,我计划稍后将它们移出。您的解决方案有效。谷歌搜索了一下,也找到了一些文档。非常感谢你!
class SourceBase(object):
    __metaclass__=abc.ABCMeta