Python使用Traits庫實現(xiàn)對象屬性
Python作為一種動態(tài)編程語言,它的變量沒有類型,這種靈活性給快速開發(fā)帶來很多便利,不過它也不是沒有缺點。Traits庫的一個很重要的目的就是為了解決這些缺點所帶來的問題。
背景
Traits庫最初是為了開發(fā)Chaco(一個2D繪圖庫)而設(shè)計的,繪圖庫中有很多繪圖用的對象,每個對象都有很多例如線型、顏色、字體之類的屬性。為了方便用戶使用,每個屬性可以允許多種形式的值。例如,顏色屬性可以是'red'、0xff0000、(255, 0, 0)
也就是說可以用字符串、整數(shù)、組元等類型的值表達顏色,這樣的需求初看起來用Python的無類型變量是一個很好的選擇,因為我們可以把各種各樣的值賦值給顏色屬性。但是顏色屬性雖然可以接受多樣的值,卻不是能接受所有的值,比如"abc"、0.5等等就不能很好地表示顏色。而且雖然為了方便用戶使用,對外的接口可以接受各種各樣形式的值,但是在內(nèi)部必須有一個統(tǒng)一的表達方式來簡化程序的實現(xiàn)。
用Trait屬性可以很好地解決這樣的問題:
- 它可以接受能表示顏色的各種類型的值
- 當給它賦值為不能表達顏色的值時,它能夠立即捕捉到錯誤,并且提供一個有用的錯誤報告,告訴用戶它能夠接受什么樣的值
- 它提供一個內(nèi)部的標準的顏色表達方式
讓我們來看一下使用traits屬性表示顏色的例子:
from enthought.traits.api import HasTraits, Color class Circle(HasTraits): color = Color
這個程序從enthought.traits.api中導(dǎo)入我們需要使用的兩個對象: HasTraits和Color。所有擁有trait屬性的類都需要從HasTraits繼承。由于Python的多繼承特性,我們很容易將現(xiàn)有的類改為支持trait屬性。Color是一個TraitFactory對象,我們在Circle類的定義中用它來聲明一個color屬性。
Traits是什么
trait為Python對象的屬性增加了類型定義的功能,此外還提供了如下的額外功能:
- 初始化:每個trait屬性都定義有自己的缺省值,這個缺省值用來初始化屬性
- 驗證:基于trait的屬性都有明確的類型定義,只有滿足定義的值才能賦值給屬性
- 委托:trait屬性的值可以委托給其他對象的屬性
- 監(jiān)聽:trait屬性的值的改變可以觸發(fā)指定的函數(shù)的運行
- 可視化:擁有trait屬性的對象可以很方便地提供一個用戶界面交互式地改變trait屬性的值
下面這個簡單的例子展示了trait所提供的這五項能力:
from enthought.traits.api import Delegate, HasTraits, Instance, Int, Str class Parent ( HasTraits ): # 初始化: last_name被初始化為'Zhang' last_name = Str( 'Zhang' ) class Child ( HasTraits ): age = Int # 驗證: father屬性的值必須是Parent類的實例 father = Instance( Parent ) # 委托: Child的實例的last_name屬性委托給其father屬性的last_name last_name = Delegate( 'father' ) # 監(jiān)聽: 當age屬性的值被修改時,下面的函數(shù)將被運行 def _age_changed ( self, old, new ): print 'Age changed from %s to %s ' % ( old, new )
下面用這兩個類創(chuàng)建立兩個實例:
>>> p = Parent() >>> c = Child()
由于沒有設(shè)置c的father屬性,因此無法獲得它的last_name屬性:
>>> c.last_name Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'last_name'
設(shè)置father屬性之后,我們就可以得到c的last_name了:
>>> c.father = p >>> c.last_name 'Zhang'
設(shè)置c的age屬性將觸發(fā)_age_changed方法的執(zhí)行:
>>> c.age = 4 Age changed from 0 to 4
調(diào)用configure_traits:
>>> c.configure_traits() True
彈出一個如下的對話框,用戶可以通過它修改c的trait屬性,
為Child類自動生成的屬性修改對話框
可以看到屬性按照其英文名排序,垂直排為一列。由于father屬性是Parent類的實例,所以它給我們一個按鈕,點此按鈕出現(xiàn)下面的設(shè)置father對象的tratis屬性的對話框
點擊Child對話框中的Father按鈕之后,彈出編輯father屬性的對話框
在上面這個對話框中修改father的Last name,可以看到child的Last name屬性也隨之發(fā)生變化。
我們可以調(diào)用print_traits方法輸出所有的trait屬性與其值:
>>> c.print_traits() age: 4 father: <__main__.Parent object at 0x13B49120> last_name: u'Zhang'
調(diào)用get方法獲得一個描述對象所有trait屬性的dict:
>>> c.get() {'age': 4, 'last_name': u'Zhang', 'father': <__main__.Parent object at 0x13B49120>}
此外還可以調(diào)用set方法設(shè)置trait屬性的值,set方法可以同時配置多個trait的屬性:
>>> c.set(age = 6) Age changed from 4 to 6 <__main__.Child object at 0x13B494B0>
動態(tài)添加Trait屬性
前面介紹的方法都是在類的定義中聲明Trait屬性,在類的實例中使用Trait屬性。由于Python是動態(tài)語言,因此Traits庫也提供了為某個特定的實例添加Trait屬性的方法。
下面的例子,直接產(chǎn)生HasTraits類的一個實例a, 然后調(diào)用其add_trait方法動態(tài)地為a添加一個名為x的Trait屬性,其類型為Float,初始值為3.0。
>>> from enthought.traits.api import * >>> a = HasTraits() >>> a.add_trait("x", Float(3.0)) >>> a.x 3.0
接下來再創(chuàng)建一個HasTraits類的實例b,用add_trait方法為b添加一個屬性a,指定其類型為HasTraits類的實例。然后把實例a賦值給實例b的屬性a:b.a。
>>> b = HasTraits() >>> b.add_trait("a", Instance(HasTraits)) >>> b.a = a
然后為實例b添加一個類型為Delegate(代理)的屬性y,它是b的屬性a所表示的實例的屬性x的代理,即b.y是b.a.x的代理。注意我們在用Delegate聲明代理時,第一個參數(shù)b的一個屬性名"a",第二個參數(shù)是是此屬性的屬性名"x",modify=True表示可以通過b.y修改b.a.x的值。我們看到當將b.y的值改為10的時候,a.x的值也同時改變了。
>>> b.add_trait("y", Delegate("a", "x", modify=True)) >>> b.y 3.0 >>> b.y = 10 >>> a.x 10.0
Traits 的使用場景
Traits 的使用場景非常廣泛,以下是一些常見的應(yīng)用場景:
1. 插件系統(tǒng)
Traits 可以用于創(chuàng)建插件系統(tǒng),使得我們可以為應(yīng)用程序添加新的功能或模塊,而無需修改現(xiàn)有的代碼。通過定義一系列的 Traits 類,我們可以輕松地將這些模塊組合起來,實現(xiàn)動態(tài)的功能擴展。
2. 用戶界面開發(fā)
Traits 提供了一種簡單而強大的方式來創(chuàng)建用戶界面。我們可以定義各種用戶界面元素的 Traits,然后將它們組合在一起以構(gòu)建復(fù)雜的界面。Traits 還支持屬性驗證和事件通知,使得我們可以輕松地處理用戶輸入和交互。
3. 數(shù)據(jù)分析和科學(xué)計算
Traits 提供了一種方便的方式來處理和分析數(shù)據(jù)。我們可以定義各種數(shù)據(jù)結(jié)構(gòu)的 Traits,然后使用這些 Traits 來創(chuàng)建和操作數(shù)據(jù)。Traits 還支持屬性驗證和默認值,使得數(shù)據(jù)處理更加健壯和可靠。
總結(jié)
Traits 是一個在 Python 中用于實現(xiàn)對象屬性的庫。Traits 可以幫助我們創(chuàng)建可復(fù)用、健壯和可擴展的代碼。在軟件開發(fā)中,Traits 是一種用于描述對象屬性的概念。一個 Trait 是一個可重用的代碼塊,它定義了一組屬性和方法,這些屬性和方法可以被其他對象繼承和使用。Traits 可以用于創(chuàng)建可插拔組件、增加代碼的可讀性和可維護性,以及提供代碼的靈活性和復(fù)用性。
相關(guān)文章
python 實現(xiàn)dict轉(zhuǎn)json并保存文件
今天小編就為大家分享一篇python 實現(xiàn)dict轉(zhuǎn)json并保存文件,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12Python?頁面解析Beautiful?Soup庫的使用方法
Beautiful?Soup?簡稱?BS4(其中?4?表示版本號)是一個?Python?中常用的頁面解析庫,它可以從?HTML?或?XML?文檔中快速地提取指定的數(shù)據(jù),這篇文章主要介紹了springboot?集成?docsify?實現(xiàn)隨身文檔?,需要的朋友可以參考下2022-09-09Python實現(xiàn)輸入若干個正整數(shù),升序后輸出
這篇文章主要介紹了Python實現(xiàn)輸入若干個正整數(shù),升序后輸出方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02