开发背景

Traits库最初是为了开发交互式绘图库Chaco而设计的。通常绘图库中有很多表示图形的对象,每个对象都有很多如线型、颜色和字体之类的属性。为了方便用户使用,每个属性可以允许多种形式的值。例如颜色属性可以是:’red’、0xff0000或者(255, 0, 0)。也就是说可以用字符串、整数或元组等类型的数据表示颜色。这样的需求初看起来用Python的无类型属性是一个很好的选择,因为我们可以把各种各样的值赋值给颜色属性。但是颜色属性虽然可以接受多样的值,却不是能接受所有的值,比如’abc’和0.5等等就不能很好地表示颜色。而且虽然为了方便用户使用,对外的接口可以接受多种类型的值,但是在程序内部必须有一个统一的表达方式简化程序内部的实现。用Trait属性可以很好地解决这样的问题:

  • 它可以接受能表示颜色的各种类型的值。
  • 当给它赋值为不能表达颜色的值时,它能够立即捕捉到错误,并且提供一个有用的错误报告,告诉用户它能够接受什么样的值。
  • 它提供一个内部的标准的表达颜色的数据类型。

下面我们通过一个简单的实例演示Trait属性的功能。

from enthought.traits.api import HasTraits, Color #

class Circle(HasTraits): #
    color = Color #

❶首先载入HasTraits和Color,推荐读者在使用Enthought公司开发的扩展库时采用和本例相同的载入方式。❷所有拥有Trait属性的类都需要从HasTraits继承。由于Python支持多继承,我们很容易将现有的类改为支持Trait属性。❸Color是一个Trait类型,在Circle类中用它定义了一个color属性。

熟悉Python的读者可能会觉得这个程序有些奇怪:按照标准的Python语法,直接在class下定义的属性color应该是Circle类的属性。而程序的目的是为Circle类的实例添加color属性。是不是应该在初始化方法__init__()中运行“self.color = Color”呢?答案是否定的,请记住Trait属性像类的属性一样定义,像实例的属性一样使用。我们不管HasTraits是如何实现这一点的,先看看如何使用Trait属性:

>>> c = Circle()
>>> Circle.color    #Circle类没有color属性
Traceback (most recent call last):
AttributeError: type object 'Circle' has no attribute 'color'
>>> c.color
wx.Colour(255, 255, 255, 255)

从上面的运行结果可以看出Circle类没有color属性,而它的实例c则拥有color属性,其缺省值为白色:“wx.Colour(255, 255, 255, 255)”,wx.Colour是wxPython界面库所使用的颜色类型。

>>> c.color = "red"
>>> c.color
wx.Colour(255, 0, 0, 255)
>>> c.color = 0x00ff00
>>> c.color
wx.Colour(0, 255, 0, 255)
>>> c.color = (0, 255, 255)
>>> c.color
wx.Colour(0, 255, 255, 255)
>>> c.color = 0.5
[[省略]]
TraitError: The 'color' trait of a Circle instance must be a string of the form
(r,g,b) or (r,g,b,a) where r, g, b, and a are integers from 0 to 255, a wx.Colour
instance, an integer which in hex is of the form 0xRRGGBB, where RR is red, GG is
green, and BB is blue or 'aquamarine' or 'black' or 'blue violet' or 'blue' or
'brown' or 'cadet blue' or 'coral' or 'cornflower blue' or 'cyan' or [[此处略去N
多英文颜色名]] or 'yellow', but a value of 0.5 <type 'float'> was specified.

由上面的运行结果可知,我们可以将’red’、0x00ff00和(0, 255, 255)等值赋给color属性,它们都被正确地转换为wx.Colour类型的值。而当赋值为0.5时抛出TraitError异常,并且显示了一个很详细的出错信息说明color属性所有能支持的值。 最后看一个很酷的功能:

>>> c.configure_traits()

执行configure_traits()之后,出现如【图:自动生成的修改颜色属性的对话框】所示的对话框界面以供我们修改颜色属性,任意选择一个颜色并按OK按钮,则configure_traits()返回True,而color属性已经变为我们通过界面所选择的颜色了:

>>> c.color
wx.Colour(64, 34, 117, 255)
如果在带“-wthread”参数的IPython中运行“c.configure_traits()”,它会立即返回False,而不会等待对话框关闭。

对于从HasTraits继承的对象,都可以调用其configure_traits()方法快速产生一个设置Trait属性的用户界面。在本例中,通过界面中的颜色输入框可以直接输入表示颜色的值,或者使用按钮打开颜色选择对话框。关于Traits库的界面方面的功能将在下一章详细介绍。

/tech/static/books/scipy/_images//traits_color.png

自动生成的修改颜色属性的对话框

上一个主题

Traits-为Python添加类型定义

下一个主题

Trait属性的功能

本页

loading...