跳转到主要内容

Zope 3持久代码/模块支持

项目描述

持久Python模块允许我们在ZODB中开发和存储Python模块,而不是在文件系统中存储。您可能需要查看zodbcode包以了解实现细节。在Zope 3中,我们将持久模块实现为实用程序。这些实用程序被称为模块管理器,用于管理源代码、编译后的模块和模块名称。然后我们提供了一个特殊的模块注册表,用于查找这些实用程序以找到模块。

详细文档

持久Python模块

持久Python模块允许我们在ZODB中开发和存储Python模块,而不是在文件系统中存储。您可能需要查看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__

但它为什么是None?因为我们还没有注册它。一旦我们注册并激活注册,就会设置一个名称

>>> 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

持久化模块框架通过类似于 sys.modules 的模块注册表与 Python 连接。Zope 3 提供了自己的模块注册表,它使用已注册的工具来查找模块

>>> 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 函数,用于在注册表中查找模块,然后在 sys.modules 中查找

>>> 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__>

持久化接口

当涉及接口时,zope.app.module 的 ModuleManagers 表现略有不同

>>> 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 树独立。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分发

zope.app.module-3.5.0.tar.gz (10.1 kB 查看散列)

上传时间

由以下支持