在类似 django 的表单实现中使用元类有啥好处?

Posted

技术标签:

【中文标题】在类似 django 的表单实现中使用元类有啥好处?【英文标题】:What are the advantages of using metaclasses in django-like form implementations?在类似 django 的表单实现中使用元类有什么好处? 【发布时间】:2011-07-25 17:47:39 【问题描述】:

首先是一些背景知识...我正在查看表单的 Django 源代码,以了解 Django 中表单的实现(并在此过程中学习一些 Python)。 Django 使用 DeclaredMetaFields MetaClass 实现表单。

这是一个类似于 Django 的表单实现的非常粗略的类图(link 用于 gist 中的示例代码)。

这是一个实例图。

这是一个非常粗略的实现同一个类而不诉诸元类(link 以示例代码在 gist)。

我了解元类概念等,并了解 Django 代码的工作原理。现在回答问题。

    除了语法优雅等明显的好处之外,元类实现还有其他好处吗? 是否可以在不借助 BoundField 之类的中间对象的情况下实现类似元类的实现?

【问题讨论】:

【参考方案1】:

句法上的好处很重要。毕竟,即使是 OOP 语言中的类也只是该语言的语法优势。

在您非常粗略地实现无元类表单实现的示例中,您描述了字典中的字段。好吧,您可能忽略了它实际上是SortedDict,因为字段的顺序很重要。所以我还需要定义fields_order 列表。

下一件大事是ModelForm。元类方法允许简单地说我使用哪个模型以及Meta 属性中的哪些字段,它会自动创建字段并将其映射到模型。如果没有元类方法,我可能不得不使用CreateFieldsFromModelMapFieldsToModel 之类的东西。或者您可以使用__init__ 方法为我执行此操作。但是等等,__init__ 方法已经够复杂了,有很多参数,比如datainitialfiles 等等。

class MyForm(Form):
    fields = 
        'one': ...
        ...
    
    fields_order = [...]
    model_fields = ???

Class MyForm2(MyForm):
    fields = MyForm.fields + ...

# ... hey this API sucks! I think I'll go with another framework.

还有更多可以在表单中配置的东西,并且所有内容都记录在案。

所以对我来说,由于庞大的配置逻辑,看起来Form 只是要求通过定义对象和工厂逻辑来实现。这里有 python 及其元类来向用户隐藏工厂。而且它很酷,因为它可以让初学者少思考。

好吧,是的,它的语法糖无处不在,而且它的全部内容都是关于使 API 易于使用。

是的,可以不使用 Metaclasses/BoundField 或其他任何东西。最后,可以在一个函数中编写所有表单实现,并在一个大字典(或 xml?)中定义所有定义,但这是否易于使用、易于理解、易于扩展?

【讨论】:

对我来说,你提出的最重要的一点是......“表单只是要求通过定义对象和工厂逻辑来实现。这里有 python 及其元类来向用户隐藏工厂。”我想我想知道是否可以在没有元类的情况下实现相同级别的 API 抽象,但是元类更干净并且对最终用户隐藏了很多细节(而且由于它们隐藏在源代码中,用户真的没有不得不为细节烦恼太多)。感谢您抽出宝贵时间回答问题。

以上是关于在类似 django 的表单实现中使用元类有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章

参数化类和元类有啥区别(请使用 Python 中的代码示例)?

模型元类与模型形式元类有何不同?

有啥方法可以将变量传递给 django 元类?

与简单地创建派生类指针相比,将基类绑定到派生类有啥好处?

如何做类似 Django 模型的元类技巧

在 django 中使用 ajax 表单发布 csrf 令牌的这种方法有啥问题?