<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            定義Traits?

            在Python程序中按照下面的步驟使用Traits庫:

            1. 從 enthought.traits.api 中載入你所需要的對象
            2. 定義你想使用的traits
            3. 從HasTraits類繼承一個新類,在其中使用你定義的traits聲明trait屬性

            通常第2、3步是放在一起的,也就是說定義traits的同時定義trait屬性,在本手冊中的大部分例子都是采用這種方式:

            from enthought.traits.api import HasTraits, Float
            
            class Person(HasTraits):
                weight = Float(50.0)
            

            這段程序定義了一個從HasTraits類繼承的Person類,在其內部聲明了一個名為weight的trait屬性,其類型為浮點數,初始值為50.0。trait屬性像類的屬性一樣定義,像實例的屬性一樣使用。下面我們來看看如何使用trait屬性:

            >>> joe = Person()
            >>> joe.weight
            50.0
            >>> joe.weight = 70.5
            >>> joe.weight = 70
            >>> joe.weight = "89"
            Traceback (most recent call last):
              File "...trait_handlers.py", line 175, in error value )
            TraitError: The 'weight' trait of a Person instance must be a float,
            but a value of '89' <type 'str'> was specified.
            

            由于joe是Person類的實例,因此它有一個名為weight的trait屬性,并且初始值為50.0。由于weight是使用Float聲明的,我們能將浮點數賦值給它,由于整數可以不丟失精度的轉換為浮點數,因此整數也可以賦值給它。然而,把浮點數賦值給整數trait屬性將會產生錯誤。由于字符串無法轉換為浮點數,因此賦值為字符串產生錯誤,錯誤的提示信息告訴我們它需要浮點數。

            有時候我們希望trait屬性能夠自動的進行強制類型轉換,這樣我們就可以將字符串賦值給類型為float的trait屬性,省去了手工轉換的麻煩。這種強制類型轉換的trait屬性都用Casting trait聲明,所有的Casting trait都是以 C 開頭的:

            from enthought.traits.api import HasTraits, CFloat
            
            class Person(HasTraits):
                cweight = CFloat(50.0)
            
            >>> bill = Person()
            >>> bill.cweight = "90"
            >>> bill.cweight
            90.0
            >>> bill.cweight = "abc"
            Traceback (most recent call last)
            ...
            

            這段程序用CFloat聲明了一個強制類型轉換的trait屬性cweight。我們可以將能轉換為浮點數的字符串"90"賦值給它,但是 "abc" 這樣的字符串賦值仍然會拋出異常。 我們可以想象CFloat的內部處理:它先將傳入的值用內部函數float()進行強制類型轉換,然后把結果賦值給trait屬性。

            我們也可以先單獨定義一個traits,然后用它來聲明多個類的多個trait屬性,下面是一個例子:

            from enthought.traits.api import HasTraits, Range
            
            coefficient = Range(-1.0, 1.0, 0.0)
            
            class quadratic(HasTraits):
                c2 = coefficient
                c1 = coefficient
                c0 = coefficient
                x  = Range(-100.0, 100.0, 0.0)
            

            在這個例子中,我們需要定義多個trait屬性,其類型都為Range(具有取值范圍的浮點值),并且范圍都是-1.0到1.0,初始值為0.0。為了體現代碼重用,我們先用coefficient = Range(-1.0, 1.0, 0.0)定義了一個traits,然后在quadratic類中使用它定義三個trait屬性:c0, c1, c2。

            預定義的Traits?

            Traits庫為Python的許多數據類型提供了預定義的trait類型。HasTraits派生的類中用trait類型名直接定義trait屬性,這個類的所有實例都將擁有一個初始化為缺省值的屬性,例如:

            class Person(HasTraits):
                age = Float
            

            上面的例子為Person類定義了一個age屬性,其類型為浮點數,并且被初始化為0.0(Float的缺省值)。如果你希望用別的值初始化trait屬性的話,可以把這個值當作參數傳遞給trait類型:

            age = Float(10.0)
            

            幾乎所有的trait類型都是可以帶括號調用的,它可以接受缺省值或者其它的參數;還可以通過關鍵字參數接受元數據。 .. TODO:: 插入元數據鏈接

            簡單類型?

            對于每個Python的簡單數據類型都對應兩種trait類型:強制類型和自動轉換類型。它們的區別在于:

            • 強制型Trait : 當這樣trait屬性被賦值為類型不匹配的數據時,會產生錯誤
            • 自動型Trait : 類型不匹配時會自動調用此類型對應的Pyton內置的轉換函數進行類型轉換
            強制型Trait 自動型Trait Python對應的數據類型 內置缺省值 自動轉換函數
            Bool CBool Boolean False bool()
            Complex CComplex Complex number 0+0j complex()
            Float CFloat Floating point number 0.0 float()
            Int CInt Plain integer 0 int()
            Long CLong Long integer 0L int()
            Str CStr String '' str()
            Unicode CUnicode Unicode u'' unicode()

            下面的例子演示了強制型Trait和自動型Trait之間的區別:

            >>> from enthought.traits.api import HasTraits, Float, CFloat
            >>> class Person ( HasTraits ):
            ...     weight  = Float
            ...     cweight = CFloat
            >>> bill = Person()
            >>> bill.weight  = 180    # OK, 整數和浮點數匹配(轉換為浮點數而不丟失信息)
            >>> bill.cweight = 180    # OK,
            >>> bill.weight  = '180'  # Error, 字符串和浮點數不匹配
            >>> bill.cweight = '180'  # OK, 調用float('180')轉換為浮點
            >>> print bill.cweight
            180.0
            

            其它類型?

            除了簡單類型以外,Traits庫還定義了許多其他的常用的數據類型。幾乎所有的Trait類型都可以直接使用其名稱或者當作函數調用,并且可以接受多種參數。

            • Any : 任何對象;

              Any( [value = None, **metadata] )
            • Array : numpy的數組;

              Array( [dtype = None, shape = None, value = None, typecode = None, **metadata] )
            • Button : 按鈕類型,通常用來觸發事件,參數都是用來描述界面中的按鈕的樣式;

              Button( [label ="", image = None, style = "button", orientation = "vertical", width_padding = 7, height_padding = 5, **metadata] )
            • Callable : 可調用對象;

              Callable( [value = None, **metadata] )
            • CArray : 可自動轉換類型的numpy數組; 調用的參數和Array相同

            • Class : Python老式類;

              Class( [value, **metadata] )
            • Code : 某種編程語言的字符串;

              Code( [value = "", minlen = 0, maxlen = sys.maxint, regex = "", **metadata] )
            • Color : 界面庫中所采用的顏色對象;

              Color( [*args, **metadata] )
            • CSet : 自動轉換類型的集合對象;

              CSet( [trait = None, value = None, items = True, **metadata] )
            • Constant : 常量對象,其值不能改變,必須指定初始值;

              Constant( value*[, ***metadata] )
            • Dict : 字典對象,系統還定義了一系列關鍵字為字符串的字典trait類型:DictStrAny, DictStrBool, ...;

              Dict( [key_trait = None, value_trait = None, value = None, items = True, **metadata] )
            • Directory : 表示某個目錄的路徑的字符串;

              Directory( [value ="", auto_set = False, entries = 10, exists = False, **metadata] )
            • Disallow : 表示不容許任何值,在帶有通配符的trait屬性定義中使用

            • Either : 多個trait類型的復合對象,例如 Either(Str, Float) 表示其定義的屬性類型可以是字符串或者浮點數;

              Either( val1*[, *val2, ..., valN, **metadata] )
            • Enum : 枚舉數據,其值可以是候選值中的一個;

              Enum( values*[, ***metadata] )
            • Event : 觸發事件用的對象;

              Event( [trait = None, **metadata] )
            • Expression : Python的表達式對象;

              Expression( [value ="0", **metadata] )
            • File : 表示包括路徑的文件名的字符串;

              File( [value = "", filter = None, auto_set = False, entries = 10, exists = False, **metadata ] )
            • Font : 界面庫中表示字體的對象;

              Font( [*args, **metadata] )

            This和self?

            在預定義的traits中,This和self需要單獨說明一下。它們所定義的屬性必須是包含此屬性的類(或派生類)的對象。This的缺省值為None,而self的缺省值則是包含屬性的對象本身。

            下面來看一個例子:

            class Employee(HasTraits):
                manager = self
            

            定義了一個Employee類,它有一個manager屬性,其類型為Employee,缺省值為對象本身:

            >>> e = Employee()
            >>> e.manager
            <__main__.Employee object at 0x05DB72A0>
            >>> e
            <__main__.Employee object at 0x05DB72A0>
            

            如果用This定義的話,那么缺省值為None。

            一般來說,屬性為某個類的實例時可以這樣定義:

            manager = Instance(Empolyee)
            

            但是對于這個例子中,在定義manager屬性時,Empolyee還不存在,因此無法如此定義。如果你喜歡這種方式的話,可以用Instance("Empolyee")來定義,當兩個類的屬性交叉引用時,可以使用這種字符串的方式來定義。

            This和self不但可以表示類本身,還可以表示派生的類:

            >>> from enthought.traits.api import HasTraits, This
            >>> class Employee(HasTraits):
            ...    manager = This
            ...
            >>> class Executive(Employee):
            ...  pass
            ...
            >>> fred = Employee()
            >>> mary = Executive()
            >>> fred.manager = mary
            >>> mary.manager = fred
            

            列出可能的值?

            使用Enum可以定義枚舉類型,在Enum的定義中給出所有可能的值,這些值必須是Python的簡單數據類型,例如字符串、整數、浮點數等等,各個可能的值的類型可以不一樣。可以直接將可能的值作為參數,或者將其包在某個list中,第一個值為缺省值:

            class Items(HasTraits):
                count = Enum(None, 0, 1, 2, 3, "many")
                # 或者:
                # count = Enum([None, 0, 1, 2, 3, "many"])
            

            下面是運行結果:

            >>> item = Items()
            >>> item.count = 2
            >>> item.count = "many"
            >>> item.count = 5
            

            如果你希望候選值是可以變化的話,可以用values關鍵字指定定義侯選值的屬性名:

            class Items(HasTraits):
                count_list = List([None, 0, 1, 2, 3, "many"])
                count = Enum(values="count_list")
            

            我們定義一個count_list列表,然后在Enum定義中用values關鍵字指定候選值為count_list屬性。

            >>> item = Items()
            >>> item.count = 5
            Traceback (most recent call last)
            #... 略去錯誤提示,此錯誤提示無法顯示侯選值列表
            >>> item.count_list.append(5)
            >>> item.count = 5
            >>> item.count
            5
            

            Trait的元數據?

            Trait對象可以有元數據屬性,這些屬性保存在HasTraits對象的trait字典中,為了解釋什么是trait字典和元數據,讓我們先來看一個例子:

            from enthought.traits.api import *
            
            class MetadataTest(HasTraits):
                i = Int(99)
                s = Str("test", desc="a string trait property")
            
            test = MetadataTest()
            

            在IPython中運行了上面的程序之后,我們對test進行如下操作:

            >>> test.traits()
            {'i': <enthought.traits.traits.CTrait object at 0x05D44EA0>,
            'trait_added': <enthought.traits.traits.CTrait object at 0x05D17CE8>,
            's': <enthought.traits.traits.CTrait object at 0x05D44EF8>,
            'trait_modified': <enthought.traits.traits.CTrait object at 0x05D17C90>}
            
            >>> test.trait("i")
            <enthought.traits.traits.CTrait object at 0x05D44EA0>
            
            >>> test.trait("s").desc
            'a string trait property'
            

            通過調用HasTraits對象的traits方法可以得到一個包含其所有trait對象的字典。請注意,trait屬性和trait對象是兩個東西:

            • trait屬性 : 用于保存實際的值,例如:test.i, test.s
            • trait對象 : 用于描述trait屬性,例如:test.trait("i"), test.trait("s")

            也就是說對于每一個trait屬性都有一個與之對應的trait對象描述它。而元數據就是保存在trait對象中的額外的描述屬性用的數據。我們看到test的trait對象除了i和s之外,還有trait_added和trait_modified,著兩個在HasTraits類中定義。

            元數據可以分為三類:

            • 內部屬性 : 這些屬性是trait對象自帶的,只讀不能寫
            • 識別屬性 : 這些屬性是可以自由地設置的,它們可以改變trait的一些行為
            • 任意屬性 : 用戶自己添加的屬性,需要自己編寫程序使用它們

            內部元數據?

            下面的這些元數據屬性在Traits庫內部使用,用戶可以讀取它們的值。

            • array : 是否是數組,不是數組的trait對象沒有此屬性

            • default : 對應的trait屬性的缺省值。也就是說: trait屬性的缺省值是保存在與其對應的trait對象的元數據屬性default中的:

              >>> test.trait("i").default
              99
              
            • default_kind : 一個描述缺省值的類型的字符串,其值可以是 value, list, dict, self, factory, method等:

              >>> test.trait("i").default_kind
              'value'
              
            • inner_traits : 內部的trait對象,在List, Dict等中使用,表示List和Dict內部對象的類型

            • trait_type : 描述trait屬性的數據類型的對象。下面的例子中,得到的就是定義trait屬性時所用的Int類的對象:

              >>> test.trait("i").trait_type
              <enthought.traits.trait_types.Int object at 0x05DBD2D0>
              
            • type : trait屬性的分類,可以是constant, delegate, event, property, trait

              >>> test.trait("i").type
              'trait'
              

            能識別的元數據?

            下面的元數據屬性不是預定義的,但是可以被HasTraits對象使用:

            • desc : 描述trait屬性用的字符串,在界面中使用
            • editor : 指定一個生成界面時用何種TraitEditor編輯對應的trait屬性
            • label : 界面中的trait屬性編輯器的標簽中的字符串
            • rich_compare : 指定判斷trait屬性值發生變化的方式。True(缺省)表示按值比較;Flase表示按照對象指針比較
            • trait_value : 指定trait屬性是否接受TraitValu類的對象,缺省值為False。當它為True時,將trait屬性設置為TraitValue(),將重置trait屬性值為缺省值。
            • transient : 指定當對象被保存(持久化)時是否保存此trait屬性值。對于大多數trait屬性來說,它的缺省值都是True。

            首頁目錄

            上一篇文章

            Traits使用手冊

            下一篇文章

            Trait事件處理

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线