如何调用python声明性属性模式

Posted

技术标签:

【中文标题】如何调用python声明性属性模式【英文标题】:How python declarative attribute pattern is called 【发布时间】:2017-04-21 14:32:30 【问题描述】:

允许将对象实例变量定义为类变量的模式的名称是什么?

通常python对象属性定义在__init__方法中。很少有库允许在 __init__ 之外定义对象属性:

# django models
class User(Model):
    name = fields.StringField()
    lastname = fields.StringField()

# django forms
class LoginForm(Form)
    username = fields.StringField()
    password = fields.PasswordField()

# elasticsearch_dsl
class Post(DocType):
    title = Text()
    created_at = Date()
    published = Boolean()

这个图案叫什么名字?

【问题讨论】:

【参考方案1】:

Django、Elasticsearch DSL 和许多其他包允许类级变量声明/强制实例类型变量、强化行为、转换。 我认为这种模式没有一个正式的名称,但通常称为:

声明式样式类 API 声明性类定义 声明性 API 类 声明性类属性 现代类 DSL

请注意,“设计模式”一词是在“真正的”OOP 语言(如 Java 和 Smalltalk)的上下文中定义的,作为处理一些缺点的一种方式,而不一定适用于特定于 Python 的解决方案。例如,函数式程序员否认工作设计模式适用于函数式编程(因为它完全没有任何缺点:) 因此,很可能,这里没有声明性属性的正式名称。也许,“惯用的”Python Class DSL 可能比“模式”更好。

虽然此类 API 提供其他控件,例如不同的父类、钩子等,但最引人注目的功能是使用类变量来模拟命名相似的实例变量。

现代 Class DSL API 通常用于model transformation、Active-Record 或 Data-Mapper 模式,但也不限于此。

Django是Active-Record实现的经典例子,由3定义为f

活动记录模式是一种访问数据的方法 数据库。数据库表或视图被包装到一个类中。因此,一个 对象实例绑定到表中的单行......包装类 为表中的每一列实现访问器方法或属性,或 查看。

"

这种“神奇”的面向类的声明式 API 包所基于的技术称为元编程。甚至 Python 也没有任何方法可以开箱即用地声明对象或类变量,它提供了通过元编程、特定 DSL API 来创建此类声明的方法,Django、SQL Alchemy、Elastic Search 等都利用了这种方法,通常使用类变量。虽然类变量 DSL 最常用于其他模型/格式的对象序列化,但旨在改进和“dedunderifying”Python OOP 的通用类声明包通常并非闻所未闻,例如https://github.com/python-attrs/attrs

附注:

现代类 API DSL 类似于 a) 实例变量/属性声明静态语言 b) 基于原型的编程(至少如果你 回想一下,类本身就是一个对象)。这很容易掌握 适用于具有一些静态或 js 背景的开发人员。

就我个人而言,我对普通的经典 DSL 没问题,尽管人们普遍认为 DSL 对于普通程序员来说学习开销太大,前提是 文档通常很少,对 DSL 设计的任何更改都可能 需要高于平均水平的技能,因此 OO 建模在企业软件中效果最好 发展。

【讨论】:

属性是在 init 中设置的,没有真正定义... 可能是 ORM 类模型定义 ... Class(y) DSL ... 声明性类级别建模?一些手册将其称为“在 SQLAlchemy 或 Django 等其他流行的 ORM 中看到的声明式样式”。 docs.peewee-orm.com/en/latest/peewee/models.html 加上可能要删除的 ORM 表单。然而,所有示例仍然是一些模型转换声明性 API。我敢打赌,在 API 和模型转换之外很少需要这种模式(构造函数/初始化器继承自超类 + 声明属性)。所以现在只是声明性 API 类/声明性类属性。这个短语也涵盖了一个类用于声明其他类属性或对象属性的情况。您可能希望浏览几个动态 ORMS,它们充满了可能适合您需要的花哨术语。 抱歉重复了。 init 仅用于初始化,而不是声明。如果您希望您有两种模式/技术 - 具有类属性的字段声明/数据建模,以及使用继承的初始化方法进行初始化。 方法,用于开发这种“神奇”的面向类的声明式API,在python元编程中被调用jakevdp.github.io/blog/2012/12/01/… dedunderification(很酷的软件包/帅哥将应用程序编码人员从繁重的学习和使用任何双下划线方法中解脱出来)。 Dunder 本身就是双下划线的简短、酷炫和紧凑的同义词。

以上是关于如何调用python声明性属性模式的主要内容,如果未能解决你的问题,请参考以下文章

Swagger PHP:如何声明属性以使用模式定义?

在 C++ 中声明可见性/访问的方式有何不同?

如何使用 SQLAlchemy Postgres ORM 的声明性基础动态创建具有列名和字典约束的表?

python 简单的帮助器,支持Postgresql 10的声明性分区功能。

高阶函数:声明实现(定义)与调用

如何在函数调用模式中使用“this”关键字?