Dio*_*nes 2 python introspection python-datamodel
我正在为我的程序编写一个插件系统,我无法解决一件事:
class ThingLoader(object):
'''
Loader class
'''
def loadPlugins(self):
'''
Get all the plugins from plugins folder
'''
from diones.thingpad.plugin.IntrospectionHelper import loadClasses
classList=loadClasses('./plugins', IPlugin)#Gets a list of
#plugin classes
self.plugins={}#Dictionary that should be filled with
#touples of objects and theirs states, activated, deactivated.
classList[0](self)#Runs nicelly
foo = classList[1]
print foo#prints <class 'TestPlugin.TestPlugin'>
foo(self)#Raise an exception
Run Code Online (Sandbox Code Playgroud)
测试插件看起来像这样:
import diones.thingpad.plugin.IPlugin as plugin
class TestPlugin(plugin.IPlugin):
'''
classdocs
'''
def __init__(self, loader):
self.name='Test Plugin'
super(TestPlugin, self).__init__(loader)
Run Code Online (Sandbox Code Playgroud)
现在IPlugin看起来像这样:
class IPlugin(object):
'''
classdocs
'''
name=''
def __init__(self, loader):
self.loader=loader
def activate(self):
pass
Run Code Online (Sandbox Code Playgroud)
所有的IPlugin类都由它们自己完美无缺,但是当被ThingLoader调用时,程序会获得异常:
File "./plugins\TestPlugin.py", line 13, in __init__
super(TestPlugin, self).__init__(loader) NameError:
global name 'super' is not defined
Run Code Online (Sandbox Code Playgroud)
我环顾四周,我根本不知道发生了什么.
bob*_*nce 20
'super'是内置的.除非你不顾一切地删除内置函数,否则你不应该看到"未定义全局名称'super'".
我正在查看您的用户网站链接,其中有一个IntrospectionHelper转储.没有缩进就很难阅读,但看起来你可能正是这样做的:
built_in_list = ['__builtins__', '__doc__', '__file__', '__name__']
for i in built_in_list:
if i in module.__dict__:
del module.__dict__[i]
Run Code Online (Sandbox Code Playgroud)
这是原始模块,你在那里改变,而不是你将要返回的信息副本!从实时模块中删除这些成员,你可以期待比"超级"更多的东西.
很难跟踪该模块正在做什么,但我的反应是它有太大的魔力.平均Python程序永远不需要乱搞导入系统,sys.path和monkey-patching __magic__模块成员.一点点魔法可以是一个巧妙的技巧,但这是非常脆弱的.只是在浏览它之后,代码可能被以下内容破坏:
从getClassDefinitions,extractModuleNames和isFromBase等令人难以置信的全面函数来看,我觉得你仍然需要学习Python工作原理的基础知识.(线索:分别是getattr,module .__ name__和issubclass.)
在这种情况下,现在不是潜入进口魔术的时候了!这很难.相反,做正常的Python方式.在包的mypackage/__ init__.py的底部说一下可能更多的打字:
from mypackage import fooplugin, barplugin, bazplugin
plugins= [fooplugin.FooPlugin, barplugin.BarPlugin, bazplugin.BazPlugin]
Run Code Online (Sandbox Code Playgroud)
但它会起作用并且在任何地方都能被理解,而不依赖于一堆复杂,脆弱的魔法.
顺便说一句,除非你计划进行一些深入的多重继承工作(并且现在可能不是时间),你甚至可能不需要使用super().调用已知超类的通常的"IPlugin .__ init __(self,...)"方法是直截了当的事情; super()并不总是"更新,更好的做事方式",在你开始使用之前,你应该了解一些事情.