Zope 3持久代码/模块支持
zope.app.module的Python项目详细描述
持久的python模块允许我们在 与将它们存储在文件系统上相反的是zodb。你可能想看看 有关实现的详细信息,请参见zodbcode包。在Zope 3中,我们 实现了作为实用程序的持久模块。这些实用程序称为 管理源代码、已编译模块和 模块。然后,我们提供一个特殊的模块注册表来查找实用程序 找到模块。
详细文档
持久的python模块
持久的python模块允许我们在 与将它们存储在文件系统上相反的是zodb。你可能想看看 有关实现的详细信息,请参见zodbcode包。在Zope 3中,我们 实现了作为实用程序的持久模块。这些实用程序称为 管理源代码、已编译模块和 模块。然后,我们提供一个特殊的模块注册表来查找实用程序 找到模块。
模块管理器
只需实例化一个新的模块管理器即可:
>>> from zope.app.module.manager import ModuleManager >>> manager = ModuleManager()
如果我创建的管理器没有参数,则没有源代码:
>>> manager.source ''
当我们添加一些代码时
>>> manager.source = """\n ... foo = 1 ... def bar(): return foo ... class Blah(object): ... def __init__(self, id): self.id = id ... def __repr__(self): return 'Blah(id=%s)' % self.id ... """
我们可以获取编译后的模块并使用创建的对象:
>>> module = manager.getModule() >>> module.foo 1 >>> module.bar() 1 >>> module.Blah('blah') Blah(id=blah)
我们还可以询问模块的名称:
>>> manager.name >>> module.__name__
但为什么它没有?因为我们还没有登记。一旦我们注册 并激活注册将设置一个名称:
>>> from zope.app.testing import setup >>> root = setup.buildSampleFolderTree() >>> root_sm = setup.createSiteManager(root)>>> from zope.app.module import interfaces >>> manager = setup.addUtility(root_sm, 'mymodule', ... interfaces.IModuleManager, manager)>>> manager.name 'mymodule'>>> manager.getModule().__name__ 'mymodule'
接下来,让我们确保模块的持久性正常工作。这样做 让我们创建一个数据库并将根文件夹添加到其中:
>>> from ZODB.tests.util import DB >>> db = DB() >>> conn = db.open() >>> conn.root()['Application'] = root>>> import transaction >>> transaction.commit()
现在,让我们重新打开数据库,测试是否可以从 不同的连接。
>>> conn2 = db.open() >>> root2 = conn2.root()['Application'] >>> module2 = root2.getSiteManager().queryUtility( ... interfaces.IModuleManager, 'mymodule').getModule() >>> module2.foo 1 >>> module2.bar() 1 >>> module2.Blah('blah') Blah(id=blah)
模块查找API
持久模块框架钩住python的方式是通过模块 类似于sys.modules的注册表。Zope3提供了自己的 使用已注册实用程序查找模块的模块注册表:
>>> from zope.app.module import ZopeModuleRegistry >>> ZopeModuleRegistry.findModule('mymodule')
但是为什么我们没有把模块拿回来呢?因为我们还没有设置站点:
>>> from zope.app.component import hooks >>> hooks.setSite(root)
现在它将找到模块,我们可以检索所有持久性 课程名称:
>>> ZopeModuleRegistry.findModule('mymodule') is module True >>> ZopeModuleRegistry.modules() [u'mymodule']
此外,该包还提供了两个api函数,用于在 注册表,然后在系统模块中::
>>> import zope.app.module >>> zope.app.module.findModule('mymodule') is module True >>> zope.app.module.findModule('zope.app.module') is zope.app.module True
第二个函数可用于查找任何模块中的对象:
>>> zope.app.module.resolve('mymodule.foo') 1 >>> zope.app.module.resolve('zope.app.module.foo.resolve')
为了在真实的python代码导入语句中使用这个框架,我们需要 要安装导入程序挂钩,通常是通过事件订阅服务器来完成的:
>>> import __builtin__ >>> event = object() >>> zope.app.module.installPersistentModuleImporter(event) >>> __builtin__.__import__ # doctest: +ELLIPSIS <bound method ZopePersistentModuleImporter.__import__ of ...>
现在我们可以简单地导入持久模块:
>>> import mymodule >>> mymodule.Blah('my id') Blah(id=my id)
最后,我们再次注销挂钩:
>>> zope.app.module.uninstallPersistentModuleImporter(event) >>> __builtin__.__import__ <built-in function __import__>
持久接口
当 涉及接口:
>>> from zope.app.module.manager import ModuleManager >>> manager = ModuleManager() >>> source = """\n ... from zope.interface import Interface ... class IFoo(Interface): pass ... class IBar(IFoo): pass ... """ >>> manager.source = source
moduleManager只有在注册后才能获得名称,并且 zodbcode包装器在没有名称的情况下中断,因此我们无法检索 我们的经理注册之前的模块:
>>> from zope.app.testing import setup >>> from zope.app.module import interfaces >>> root = setup.buildSampleFolderTree() >>> root_sm = setup.createSiteManager(root) >>> manager = setup.addUtility(root_sm, u'foo', ... interfaces.IModuleManager, manager)
现在我们可以编译一个带有接口的模块并访问所有内容 适当:
>>> module = manager.getModule() >>> module <PersistentModule foo> >>> module.IFoo <PersistentInterfaceClass foo.IFoo> >>> module.IBar <PersistentInterfaceClass foo.IBar>
变化
3.5.0(2009-02-01)
- 使用zope.container而不是zope.app.container。
3.4.0(2007-10-25)
- 独立于主zope树的初始发布。