【问题标题】:Is there a way to emulate the __prepare__ special method of a Python 3-metaclass in Python 2.5?有没有办法在 Python 2.5 中模拟 Python 3 元类的 __prepare__ 特殊方法?
【发布时间】:2011-04-21 16:20:46
【问题描述】:

在我的项目中,我必须坚持使用 Python 2.5(Google App Engine)。在应用程序的某个地方(实际上是一个框架),我必须跟踪定义了哪些变量以及定义它们的顺序,换句话说,我想在处理赋值运算符时进行拦截。

使用 Python 3,我将使用 __prepare__ 方法定义一个元类 M,该方法返回一个智能字典,该字典跟踪它何时被访问。然后我只需要使用元类 M 执行类语句中的所有内容。

有没有办法在 Python 2.5 中模拟这一点?

我想要达到的目标示例

使用 Python 3 的元类方法,我可以实现像引用一样工作的变量,例如 M 可以这样

# y is a callable
class C(metaclass=M):
    x = ref(y)
    x = 1

将与y(1) 等效(直到创建C),即黑盒ref 函数对C 字典中变量的第一次赋值会创建此变量。进一步的赋值只需调用 ref 函数的参数。

【问题讨论】:

  • 我有点困惑。您只想在类语句中执行分配以跟踪顺序还是您真的想要生成的类?
  • @Aaron:我只对字典的填充方式感兴趣,而不是对结果的实际类感兴趣。使用 new 特殊方法,我什至可以跳过在 Python 2.5 中已经工作的结果类的创建。但是,我可能会使用 new 来报告我的字典(如果它是在 prepare 中创建的)。元类 M 的类将是字典而不是类。
  • 是orderdict我们的排除?尽管这是一个有趣的问题,但我真的想不出办法。
  • @Aaron。我什至不知道如何在 Python 2.5 中使用有序字典。
  • 这很容易实现。

标签: python python-3.x metaclass


【解决方案1】:

您可以使用包装器来包装用于填充类的变量,该包装器在内部保留一个计数器并分配一个递增的值。包装器可以被子类化以用于标记或向变量添加行为。您将使用变量值对它们进行排序,并使用常规 Python 2 元类来拦截类的创建。

Django 是使用这种技术来记住在模型类上定义成员的顺序的项目之一。你可以看看where the fields are created;然后在__cmp__方法的实现中使用它来保持字段的创建顺序。

【讨论】:

  • 非常感谢您指出 Django 正在使用的技术。这将解决我的分配相对顺序的问题。然而,它没有解决的是跟踪分配的变量。稍后我将编辑我的问题以明确这一点。
【解决方案2】:

一个起点是查看PEP-3115 并阅读“当前”行为,例如实现 Python 3 之前的当前行为。

【讨论】:

    猜你喜欢
    • 2014-05-14
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 2014-07-15
    相关资源
    最近更新 更多