MEP13: 使用属性为艺术家#

状态#

  • 讨论

分支和拉取请求#

摘要#

使用 Python properties 包装所有的 matplotlib 获取和设置方法,使它们可以像类属性一样读取和写入。

详细描述#

目前,matplotlib 使用 getter 和 setter 函数(通常分别以前缀 get_ 和 set_ 开头)来读取和写入与类相关的数据。然而,自 2.6 版本起,Python 支持属性(properties),这使得这些 setter 和 getter 函数可以像属性一样被访问。此提案将把所有现有的 setter 和 getter 方法实现为属性。

实现#

  1. 所有现有的getter和setter方法都需要有两个别名,一个带有get_或set_前缀,另一个不带。当前缺少前缀的getter方法应记录在文本文件中。

  2. 类应该重新组织,使得设置器和获取器方法在代码中是顺序排列的,首先是获取器方法。

  3. 提供额外可选参数的获取和设置方法应通过其他方式访问这些参数,无论是作为额外的获取或设置方法,还是其他类的属性。如果这些类不可访问,则应添加它们的获取方法。

  4. 属性装饰器将被添加到没有前缀的设置器和获取器方法中。带有前缀的将被标记为已弃用。

  5. 文档字符串需要重写,以便带有前缀的获取器具有当前的文档字符串,而不带前缀的获取器具有适用于属性的通用文档字符串。

  6. 自动别名生成需要进行修改,以便它也能为属性创建别名。

  7. 所有 getter 和 setter 方法调用都需要更改为属性访问。

  8. 所有带前缀的设置器和获取器别名将被移除

以下步骤可以同时进行:1、2 和 3;4 和 5;6 和 7。

只有在同一版本中必须完成以下步骤:4、5 和 6。所有其他更改可以在单独的版本中完成。8 应在其他所有内容之后的几个宏版本中完成。

向后兼容性#

所有现有的无前缀(如get_)的getter方法都需要从函数调用改为属性访问。在大多数情况下,这只需要去掉括号。

具有额外可选参数的设置器和获取器方法将需要以另一种方式实现这些参数,可以是在同一类中的单独属性,或者是另一个类的属性或特性。

在设置器返回值的情况下,需要改为先使用设置器,然后使用获取器。

具有 set_ATTR_on() 和 set_ATTR_off() 方法的情况将被更改为 ATTR_on 属性。

示例#

axes.Axes.set_axis_off/set_axis_on#

当前实现:

axes.Axes.set_axis_off()
axes.Axes.set_axis_on()

新实现:

True = axes.Axes.axis_on
False = axes.Axes.axis_on
axes.Axes.axis_on = True
axes.Axes.axis_on = False

axes.Axes.get_xlim/set_xlim 和 get_autoscalex_on/set_autoscalex_on#

当前实现:

[left, right] = axes.Axes.get_xlim()
auto = axes.Axes.get_autoscalex_on()

[left, right] = axes.Axes.set_xlim(left=left, right=right, emit=emit, auto=auto)
[left, right] = axes.Axes.set_xlim(left=left, right=None, emit=emit, auto=auto)
[left, right] = axes.Axes.set_xlim(left=None, right=right, emit=emit, auto=auto)
[left, right] = axes.Axes.set_xlim(left=left, emit=emit, auto=auto)
[left, right] = axes.Axes.set_xlim(right=right, emit=emit, auto=auto)

axes.Axes.set_autoscalex_on(auto)

新实现:

[left, right] = axes.Axes.axes_xlim
auto = axes.Axes.autoscalex_on

axes.Axes.axes_xlim = [left, right]
axes.Axes.axes_xlim = [left, None]
axes.Axes.axes_xlim = [None, right]
axes.Axes.axes_xlim[0] = left
axes.Axes.axes_xlim[1] = right

axes.Axes.autoscalex_on = auto

axes.Axes.emit_xlim = emit

axes.Axes.get_title/set_title#

当前实现:

string = axes.Axes.get_title()
axes.Axes.set_title(string, fontdict=fontdict, **kwargs)

新实现:

string = axes.Axes.title
string = axes.Axes.title_text.text

text.Text = axes.Axes.title_text
text.Text.<attribute> = attribute
text.Text.fontdict = fontdict

axes.Axes.title = string
axes.Axes.title = text.Text
axes.Axes.title_text = string
axes.Axes.title_text = text.Text

axes.Axes.get_xticklabels/set_xticklabels#

当前实现:

[text.Text] = axes.Axes.get_xticklabels()
[text.Text] = axes.Axes.get_xticklabels(minor=False)
[text.Text] = axes.Axes.get_xticklabels(minor=True)
[text.Text] = axes.Axes.([string], fontdict=None, **kwargs)
[text.Text] = axes.Axes.([string], fontdict=None, minor=False, **kwargs)
[text.Text] = axes.Axes.([string], fontdict=None, minor=True, **kwargs)

新实现:

[text.Text] = axes.Axes.xticklabels
[text.Text] = axes.Axes.xminorticklabels
axes.Axes.xticklabels = [string]
axes.Axes.xminorticklabels = [string]
axes.Axes.xticklabels = [text.Text]
axes.Axes.xminorticklabels = [text.Text]

替代方案#

除了使用装饰器,也可以使用属性函数。这将改变程序,使得所有缺少前缀的获取方法都需要重命名或删除。这使得处理文档字符串更加困难且难以阅读。

不需要弃用设置和获取方法,但保留它们会使代码复杂化。

这也可以作为一个机会来重写甚至移除自动别名生成。

另一个替代提案:

set_xlimset_xlabelset_title 等转换为 xlimxlabeltitle,...,以使从 plt 函数到 axes 方法的转换显著简化。这些仍然是方法,而不是属性,但在保留接口的同时,它仍然是一个巨大的可用性增强。