允许python代码存在于zodb中

zodbcode的Python项目详细描述


详细文档

持久模块

文档概述

本文档旨在获取有关持久模块的技术信息 指导和记录他们的设计。

目标

这些目标主要来自Zope3。值得考虑一下 其他应用程序。

  • 持久模块用于支持使用 ZODB.

  • 可以使用网络客户端(如Web浏览器和 文件同步工具。

  • 无需 服务器重新启动。

  • 持久化模块利用一个熟悉的模型模块来管理python 软件。

  • 持久模块可以使用zope同步到文件系统 文件系统同步框架。持久模块是同步的 目的包括:

    o使用传统工具,如编辑器和代码分析工具

    o修订控制

    理想情况下,文件系统表示将由python源代码组成 文件

用例
  • 创建实现zope 3组件的类和函数。

    o实用程序、适配器、视图、服务类和工厂。

    < DL>
    o通常是持久的和/或

    可腌制。

  • 定义接口,包括模式

  • 从其他模块导入类、函数和接口。

  • 从其他持久对象导入类、函数和接口。为了 例如,适配器注册对象可能直接引用 持久模块定义类。

  • 更改模块源

    • 更改反映在模块状态中
    • 更改将反映在导入其他模块的对象中。
  • 将模块与文件系统表示同步。

边缘案例

< Buff行情> ????

基本功

python模块的设计不是为了在运行时更改。A的来源 python模块通常在python程序运行时不会更改。 有一个粗糙的重新加载工具,允许模块手动重新加载到 处理源更改。

python模块包含可变状态。模块有一个字典,可能是 由应用程序代码修改。它可能包含在 运行时间。它按类型用于实现全局注册表。

当一个模块被重新加载时,它会被一个字典重新执行,这个字典包括 上次执行的结果。

使用zodb的程序可以说具有超过 单个进程的生存期。此外,程序可能存在于 具有重叠运行时间的多个单独进程。

持久程序的生存期足够长,很可能 模块源代码将在程序生命周期内更改。

问题

模块的状态应该用模块源来表示吗?

考虑以下可能性:

  1. 模块状态由其源代码庄严地表示。
  • 这将背离标准python模块的行为。 标准python模块保留一个不被覆盖的模块字典。 通过重新加载。python模块可以从外部进行变异,并且可以包含 在运行时修改的可变数据结构。

    一个普通模块的状态不是持久的或共享的帐户 过程。

    对于标准的python模块,可以将模块源代码看作 模块初始状态的表达式。(这不太对 或者,因为有些模块是以他们预期的方式编写的 模块重新加载。)

  • 从模块源中删除已由其他人导入的变量 模块或对象将导致导入的值断开连接 从模块的源代码。即使以后再添加变量, 以前导入的值将被断开。

    引入一个数据结构来记录从 模块。例如,假设模块m1从m2导入x。很有诱惑力 在m2中记录这个事实,这样我们就不允许m2被移除或被移除 改变的方式使得m2不再定义x。不幸的是 将引入M2源未捕获的状态。

  • 持久模块只能用于软件。你不可能 使用它们存储可变数据,例如 在执行模块源程序之外更新。

  1. 模块状态不是由它的源严格表示的。
< Buff行情>
  • 可能会允许可变数据,例如 持久模块。

  • 很难看到模块的状态。如果一个模块 包含可变数据,您需要某种方法来获取该数据,以便 可以检查和操作它。

  • 当模块同步到文件系统时,您需要同步 它是源代码,您还需要在一些 方式。内容的同步可以使用xml pickle完成,但是 使用基于文件系统的工具管理数据会很麻烦。

    最后,两个表示之间会出现重复的数据。它 以一致的方式管理重复的数据会很麻烦。

  1. 模块状态由它的源庄严地表示,但是允许额外的元 数据:

    这与选项A相同,只是我们支持元数据管理。这个 元数据可以包括依赖关系信息。我们会追踪外部 使用(导入)模块变量以影响是否删除 允许使用模块或定义的变量,或者在以下情况下是否发出警告 变量被删除。

    注意,元数据的管理不必由 模块。这可以通过应用程序定义的工具来完成,在 在这种情况下,模块设施需要为 实现用于管理此信息的挂钩。

特殊情况

本节包含的示例可能会对持久性 模块或可能激发或突出上述问题的模块,

  • 持久类

    持久类包括不由该类表示的数据 来源。类缓存从基类继承的插槽定义。这个 是仅由其源间接表示的信息。 类似地,类管理其子类的集合。这允许 当新的槽定义为 已分配(通过setattr)。子类的缓存槽和集合是 不是持久类状态的一部分。它没有保存在数据库中,但是 当类加载到内存中或当它是子类时重新计算 已加载到内存中。

    考虑两个持久化模块m1,它定义类c1,和m2,后者 定义C2类。C2子类C1。c1定义了一个getitem槽,它 由C2继承和缓存。

    假设我们有一个进程p1,内存中有m1和m2。P1中的C2 一个(缓存的)getitem插槽,填充从中的c1继承的定义 P1p1中的c1在它的集合中有c2子类的。在p1中,我们修改m1, 通过编辑和重新编译其源代码。当我们重新编译m1的源代码时 通过调用c1的setState方法更新c1的状态,并传递新的 类字典。setState方法将依次使用setAttr 从新字典中分配值。如果我们设置了slot属性, _ c1中的setattribute方法将通知它的每个子类 插槽已更改。现在,假设我们添加了一个 当我们修改消息来源时。当我们在c1,c2中设置 将被通知有新的"len"插槽定义。

    假设我们有一个进程p2,它也将m1和m2加载到内存中。 在p1中,p2中的c2缓存getitem插槽,p2中的c1缓存p2中的c2 它是子类的集合。现在,当p1中的m1被修改并且 相应的事务被提交,m1和所有 它定义的持久对象(包括c1)被发送到所有其他对象 过程。当p2得到c1的失效时,它使c1失效。它 持久类不允许成为幽灵。当A 持久类无效,它会立即重新加载其状态,而不是 把自己变成鬼魂。当C2的状态在P2中重新加载时,我们 从新的类字典中分配它的属性。当我们分配插槽时, 我们通知它的子类,包括p2中的c2。

    假设我们有一个进程p3,它的内存只有m1。在p3中,m2不是 在记忆中,也不是它的任何子对象。在P3中,C2不在 c1的子类集合,因为c2不在内存中,并且 子类集合是c1的易失性数据。当我们修改p1中的c1时 并提交事务,p3中c1的状态将被更新,但是 C2的状态在P3中不受影响,因为它不在内存中。

    最后,考虑一个进程p4,它的内存中有m2,但没有m1。M2是 不是鬼,所以C2在记忆里。既然c2在内存中,c1必须在 内存,即使m1不在内存中,因为c2有对c1的引用。 此外,c1不能是ghost,因为不允许持久类 做鬼魂。当我们在p1中提交更新m1的事务时, c1的失效被发送到p4并且c1被更新。当c1更新时, 它的子类(在p4中),包括c2被通知,以便它们的缓存 插槽定义已更新。

    当我们修改m1时,c1和c2内存中的所有副本都会正确更新, 即使他们缓存的数据不是持久缓存的。这行得通,而且 只起作用,因为持久类永远不是幽灵。如果一个班能 做鬼魂,那么无效就没有效果,也没有鬼魂 依赖类不会被更新。

  • 持久接口

    与类一样,zope接口缓存某些信息。接口 维护一组它扩展的所有接口。此外, 接口维护其所有子接口的集合。这个 子接口集合用于在 接口更改。

    < DL>
    (接口是更一般的对象类的特例,称为
    "规范",包括接口和接口声明。 对其他规范和相关数据执行类似的缓存 结构。不过,为了简化讨论,我们将仅限于 接口。)

    在设计持久接口时,我们有其他方法 考虑:

    1. 我们可以采用与持久类相同的方法。 我们不会永久保存缓存的数据。我们会把它计算成 对象被移到内存中。

      要采用这种方法,我们还需要创建持久接口 不可重影。这是正确处理对象所必需的 变化:

      有人可能会说,如果类是一个必要的疣,非幽灵性。 python类的细节强加于我们控制, 我们应该避免创建需要 不可重影。

    2. 我们可以持久地存储缓存的数据。例如,我们可以存储 持久化中的扩展接口集和子接口集 词典。

      这种方法的一个显著缺点是持久接口 会累积的状态是它们的源代码中没有引用的, 但是,值得注意的是,当依赖项和缓存数据 不能从单个模块源派生,它可以从 系统中所有模块的源。我们可以实施 以执行模块代码导致 要重新计算的模块定义接口之间的所有依赖项 正确。

      < DL>
      (对我来说,这是一个有趣的例子:可以计算的状态
      从其他序列化状态反序列化期间。这不应该是 令人惊讶的是,我们实际上是在讨论用于 优化目的。)

提案

  • 模块的状态必须由 来源。该状态还可以包括以下信息,如缓存数据 是从它的源表示状态派生出来的。

    目前尚不清楚我们是否或如何执行这一规定。也许它只是一个 指南。zope中使用的模块同步适配器将仅 同步模块源。如果模块定义的状态不是 由其源表示或从其派生,则该数据将丢失在 同步。当然,不使用同步的应用程序 框架将不受此限制的影响。或者,你可以 开发处理额外模块的自定义模块同步适配器 但是,此类适配器的开发将不在 Zope项目。

注释

  • 当我们使一个持久类失效时,我们需要删除 由旧字典定义的属性,而不是由新字典定义的 班级字典。

更改

3.4.0(2007-10-10)

  • 测试版2之后没有变化,但在稳定的测试集中验证了测试成功。

3.4.0b2(2007-10-10)

  • 调整代码以使用最新版本的zodb(3.8)。
  • 已将module.txt从stx转换为rest。
  • 改进包元数据。

3.4.0b1(2007年-???10)

  • 独立于主zope树的初始版本。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
JBossJava进程内存持续增长   Java postincrement(++)在作为参数传递时表现不符合预期   TableView列的java编辑值   java根据springboot@Scheduled注释使用的条件动态修改调度程序计时   java无法将jsp表单值设置为类变量   java ParseQuery from字段未保存   java为什么日历返回月份。是否获取(Calendar.MONTH)上个月而不是当前月?   java无法获取api密钥的md5指纹   java通用DAO和嵌套属性支持   javapomi的版本已经改变了。从OJDBC6到OJDBC8的xml。使用新版本OJDBC8执行某些查询时出现锁定问题   java IntelliJ颜色方案定制   java从第三方读取Linux存储库   amazon s3在AWS s3 Java SDK中设置对象元数据   java一对多映射比