<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 3.4 Traits:創建交互對話 In?[10]: ``` %matplotlib inline import numpy as np ``` > 作者 : _Didrik Pinte_ Traits項目允許你可以向Python項目屬性方便的添加驗證、初始化、委托、通知和圖形化界面。 在這個教程中,我們將研究Traits工具包并且學習如何動態減少你所寫的鍋爐片代碼,進行快速的GUI應用開發,以及理解Enthought工具箱中其他部分的想法。 Traits和Enthought工具箱是基于BSD-style證書的開源項目。 **目標受眾** ## Python中高級程序員 **要求** * [wxPython](http://www.wxpython.org/)、[PyQt](https://riverbankcomputing.com/software/pyqt/intro)或[PySide](https://pyside.github.io/docs/pyside/)之一 * Numpy和Scipy * [Enthought工具箱](http://code.enthought.com/projects) * 所有需要的軟件都可以通過安裝[EPD免費版](https://store.enthought.com/)來獲得 **教程內容** * 介紹 * 例子 * Traits是什么 * 初始化 * 驗證 * 文檔 * 可視化: 打開一個對話框 * 推遲 * 通知 * 一些更高級的特征 ## 3.4.1 介紹 Enthought工具箱可以構建用于數據分析、2D繪圖和3D可視化的精密應用框架。這些強力可重用的組塊是在BSD-style證書下發布的。 Enthought工具箱主要的包是: * Traits - 基于組塊的方式構建我們的應用。 * Kiva - 2D原生支持基于路徑的rendering、affine轉化、alpha混合及其它。 * Enable - 基于對象的2D繪圖畫布。 * Chaco - 繪圖工具箱,用于構建復雜的交互2D圖像。 * Mayavi -基于VTK的3D科學數據可視化 * Envisage - 應用插件框架,用于構建腳本化可擴展的應用 ![](http://www.scipy-lectures.org/_images/ETS.jpg) 在這篇教程中,我們將關注Traits。 ## 3.4.2 例子 在整個這篇教程中,我們將使用基于水資源管理簡單案例的一個樣例。我們將試著建模一個水壩和水庫系統。水庫和水壩有下列參數: * 名稱 * 水庫的最小和最大容量 [$hm^3$] * 水壩的高度和寬度[$m$] * 蓄水面積[$km^2$] * 水壓頭[$m$] * 渦輪的動力[$MW$] * 最小和最大放水量[$m^3/s$] * 渦輪的效率 水庫有一個已知的運轉情況。一部分是與基于放水量有關的能量產生。估算水力發電機電力生產的簡單公式是$P = \rho hrgk$, 其中 * P 以瓦特為單位的功率, * \rho 是水的密度 ($~1000 kg/m^3$), * h 是水的高度, * r 是以每秒立方米為單位的流動率, * g 重力加速度,9.8 $m/s^2$, * k 是效率系數,范圍從0到1。 年度的電能生產取決于可用的水供給。在一些設施中,水流率在一年中可能差10倍。 運行狀態的第二個部分是蓄水量,蓄水量(storage)依賴于控制和非控制參數: $storage_{t+1} = storage_t + inflows - release - spillage - irrigation$ 本教程中使用的數據不是真實的,可能甚至在現實中沒有意義。 ## 3.4.3 Traits是什么 trait是可以用于常規Python對象屬性的類型定義,給出屬性的一些額外特性: * 標準化: * 初始化 * 驗證 * 推遲 * 通知 * 可視化 * 文檔 類可以自由混合基于trait的屬性與通用Python屬性,或者選擇允許在這個類中只使用固定的或開放的trait屬性集。類定義的Trait屬性自動繼承自由這個類衍生的其他子類。 創建一個traits類的常用方式是通過擴展**HasTraits**基礎類,并且定義類的traits : In?[1]: ``` from traits.api import HasTraits, Str, Float class Reservoir(HasTraits): name = Str max_storage = Float ``` 對Traits 3.x用戶來說 如果使用Traits 3.x, 你需要調整traits包的命名空間: * traits.api應該為enthought.traits.api * traitsui.api應該為enthought.traits.ui.api 像這樣使用traits類和使用其他Python類一樣簡單。注意,trait值通過關鍵詞參數傳遞: In?[2]: ``` reservoir = Reservoir(name='Lac de Vouglans', max_storage=605) ``` ### 3.4.3.1 初始化 所有的traits都有一個默認值來初始化變量。例如,基礎python類型有如下的trait等價物: | Trait | Python類型 | 內置默認值 | | --- | --- | --- | | Bool | Boolean | False | | Complex | Complex number | 0+0j | | Float | Floating point number | 0.0 | | Int | Plain integer | 0 | | Long | Long integer | 0L | | Str | String | '' | | Unicode | Unicode | u'' | 存在很多其他預定義的trait類型: Array, Enum, Range, Event, Dict, List, Color, Set, Expression, Code, Callable, Type, Tuple, etc。 自定義默認值可以在代碼中定義: In?[3]: ``` from traits.api import HasTraits, Str, Float class Reservoir(HasTraits): name = Str max_storage = Float(100) reservoir = Reservoir(name='Lac de Vouglans') ``` 復雜初始化 當一個trait需要復雜的初始化時,可以實施_XXX_默認魔法方法。當調用XXX trait時,它會被懶惰的調用。例如: In?[4]: ``` def _name_default(self): """ Complex initialisation of the reservoir name. """ return 'Undefined' ``` ### 3.4.3.2 驗證 當用戶試圖設置trait的內容時,每一個trait都會被驗證: In?[5]: ``` reservoir = Reservoir(name='Lac de Vouglans', max_storage=605) reservoir.max_storage = '230' ``` ``` --------------------------------------------------------------------------- TraitError Traceback (most recent call last) <ipython-input-5-cbed071af0b9> in <module>() 1 reservoir = Reservoir(name='Lac de Vouglans', max_storage=605) 2 ----> 3 reservoir.max_storage = '230' /Library/Python/2.7/site-packages/traits/trait_handlers.pyc in error(self, object, name, value) 170 """ 171 raise TraitError( object, name, self.full_info( object, name, value ), --> 172 value ) 173 174 def full_info ( self, object, name, value ): TraitError: The 'max_storage' trait of a Reservoir instance must be a float, but a value of '230' <type 'str'> was specified. ``` ### 3.4.3.3 文檔 從本質上說,所有的traits都提供關于模型自身的文檔。創建類的聲明方式使它是自解釋的: In?[6]: ``` from traits.api import HasTraits, Str, Float class Reservoir(HasTraits): name = Str max_storage = Float(100) ``` trait的**desc**元數據可以用來提供關于trait更多的描述信息: In?[7]: ``` from traits.api import HasTraits, Str, Float class Reservoir(HasTraits): name = Str max_storage = Float(100, desc='Maximal storage [hm3]') ``` 現在讓我們來定義完整的reservoir類: In?[8]: ``` from traits.api import HasTraits, Str, Float, Range class Reservoir(HasTraits): name = Str max_storage = Float(1e6, desc='Maximal storage [hm3]') max_release = Float(10, desc='Maximal release [m3/s]') head = Float(10, desc='Hydraulic head [m]') efficiency = Range(0, 1.) def energy_production(self, release): ''' Returns the energy production [Wh] for the given release [m3/s] ''' power = 1000 * 9.81 * self.head * release * self.efficiency return power * 3600 if __name__ == '__main__': reservoir = Reservoir( name = 'Project A', max_storage = 30, max_release = 100.0, head = 60, efficiency = 0.8 ) release = 80 print 'Releasing {} m3/s produces {} kWh'.format( release, reservoir.energy_production(release) ) ``` ``` Releasing 80 m3/s produces 1.3561344e+11 kWh ``` ### 3.4.3.4 可視化: 打開一個對話框 Traits庫也關注用戶界面,可以彈出一個Reservoir類的默認視圖: In?[?]: ``` reservoir1 = Reservoir() reservoir1.edit_traits() ``` ![](http://www.scipy-lectures.org/_images/reservoir_default_view.png) TraitsUI簡化了創建用戶界面的方式。HasTraits類上的每一個trait都有一個默認的編輯器,將管理trait在屏幕上顯示的方式 (即Range trait顯示為一個滑塊等)。 與Traits聲明方式來創建類的相同渠道,TraitsUI提供了聲明的界面來構建用戶界面代碼: In?[?]: ``` from traits.api import HasTraits, Str, Float, Range from traitsui.api import View class Reservoir(HasTraits): name = Str max_storage = Float(1e6, desc='Maximal storage [hm3]') max_release = Float(10, desc='Maximal release [m3/s]') head = Float(10, desc='Hydraulic head [m]') efficiency = Range(0, 1.) traits_view = View( 'name', 'max_storage', 'max_release', 'head', 'efficiency', title = 'Reservoir', resizable = True, ) def energy_production(self, release): ''' Returns the energy production [Wh] for the given release [m3/s] ''' power = 1000 * 9.81 * self.head * release * self.efficiency return power * 3600 if __name__ == '__main__': reservoir = Reservoir( name = 'Project A', max_storage = 30, max_release = 100.0, head = 60, efficiency = 0.8 ) reservoir.configure_traits() ``` ![](http://www.scipy-lectures.org/_images/reservoir_view.png) ### 3.4.3.5 推遲 可以將trait定義和它的值推送給另一個對象是Traits的有用的功能。 In?[?]: ``` from traits.api import HasTraits, Instance, DelegatesTo, Float, Range from reservoir import Reservoir class ReservoirState(HasTraits): """Keeps track of the reservoir state given the initial storage. """ reservoir = Instance(Reservoir, ()) min_storage = Float max_storage = DelegatesTo('reservoir') min_release = Float max_release = DelegatesTo('reservoir') # state attributes storage = Range(low='min_storage', high='max_storage') # control attributes inflows = Float(desc='Inflows [hm3]') release = Range(low='min_release', high='max_release') spillage = Float(desc='Spillage [hm3]') def print_state(self): print 'Storage\tRelease\tInflows\tSpillage' str_format = '\t'.join(['{:7.2f}'for i in range(4)]) print str_format.format(self.storage, self.release, self.inflows, self.spillage) print '-' * 79 if __name__ == '__main__': projectA = Reservoir( name = 'Project A', max_storage = 30, max_release = 100.0, hydraulic_head = 60, efficiency = 0.8 ) state = ReservoirState(reservoir=projectA, storage=10) state.release = 90 state.inflows = 0 state.print_state() print 'How do we update the current storage ?' ``` 特殊的trait允許用魔法_xxxx_fired方法管理事件和觸發器函數: In?[?]: ``` from traits.api import HasTraits, Instance, DelegatesTo, Float, Range, Event from reservoir import Reservoir class ReservoirState(HasTraits): """Keeps track of the reservoir state given the initial storage. For the simplicity of the example, the release is considered in hm3/timestep and not in m3/s. """ reservoir = Instance(Reservoir, ()) min_storage = Float max_storage = DelegatesTo('reservoir') min_release = Float max_release = DelegatesTo('reservoir') # state attributes storage = Range(low='min_storage', high='max_storage') # control attributes inflows = Float(desc='Inflows [hm3]') release = Range(low='min_release', high='max_release') spillage = Float(desc='Spillage [hm3]') update_storage = Event(desc='Updates the storage to the next time step') def _update_storage_fired(self): # update storage state new_storage = self.storage - self.release + self.inflows self.storage = min(new_storage, self.max_storage) overflow = new_storage - self.max_storage self.spillage = max(overflow, 0) def print_state(self): print 'Storage\tRelease\tInflows\tSpillage' str_format = '\t'.join(['{:7.2f}'for i in range(4)]) print str_format.format(self.storage, self.release, self.inflows, self.spillage) print '-' * 79 if __name__ == '__main__': projectA = Reservoir( name = 'Project A', max_storage = 30, max_release = 5.0, hydraulic_head = 60, efficiency = 0.8 ) state = ReservoirState(reservoir=projectA, storage=15) state.release = 5 state.inflows = 0 # release the maximum amount of water during 3 time steps state.update_storage = True state.print_state() state.update_storage = True state.print_state() state.update_storage = True state.print_state() ``` 對象間的依賴可以自動使用trait**Property**完成。**depends_on**屬性表示property其他traits的依賴性。當其他traits改變了,property是無效的。此外,Traits為屬性使用魔法函數的名字: * _get_XXX 來獲得XXX屬性的trait * _set_XXX 來設置XXX屬性的trait In?[?]: ``` from traits.api import HasTraits, Instance, DelegatesTo, Float, Range from traits.api import Property from reservoir import Reservoir class ReservoirState(HasTraits): """Keeps track of the reservoir state given the initial storage. For the simplicity of the example, the release is considered in hm3/timestep and not in m3/s. """ reservoir = Instance(Reservoir, ()) max_storage = DelegatesTo('reservoir') min_release = Float max_release = DelegatesTo('reservoir') # state attributes storage = Property(depends_on='inflows, release') # control attributes inflows = Float(desc='Inflows [hm3]') release = Range(low='min_release', high='max_release') spillage = Property( desc='Spillage [hm3]', depends_on=['storage', 'inflows', 'release'] ) ### Private traits. _storage = Float ### Traits property implementation. def _get_storage(self): new_storage = self._storage - self.release + self.inflows return min(new_storage, self.max_storage) def _set_storage(self, storage_value): self._storage = storage_value def _get_spillage(self): new_storage = self._storage - self.release + self.inflows overflow = new_storage - self.max_storage return max(overflow, 0) def print_state(self): print 'Storage\tRelease\tInflows\tSpillage' str_format = '\t'.join(['{:7.2f}'for i in range(4)]) print str_format.format(self.storage, self.release, self.inflows, self.spillage) print '-' * 79 if __name__ == '__main__': projectA = Reservoir( name = 'Project A', max_storage = 30, max_release = 5, hydraulic_head = 60, efficiency = 0.8 ) state = ReservoirState(reservoir=projectA, storage=25) state.release = 4 state.inflows = 0 state.print_state() ``` **注意** 緩存屬性 當訪問一個輸入沒有改變的屬性時,[[email?protected]](/cdn-cgi/l/email-protection)_property修飾器可以用來緩存這個值,并且只有在失效時才會重新計算一次他們。 讓我們用ReservoirState的例子來擴展TraitsUI介紹: In?[?]: ``` from traits.api import HasTraits, Instance, DelegatesTo, Float, Range, Property from traitsui.api import View, Item, Group, VGroup from reservoir import Reservoir class ReservoirState(HasTraits): """Keeps track of the reservoir state given the initial storage. For the simplicity of the example, the release is considered in hm3/timestep and not in m3/s. """ reservoir = Instance(Reservoir, ()) name = DelegatesTo('reservoir') max_storage = DelegatesTo('reservoir') max_release = DelegatesTo('reservoir') min_release = Float # state attributes storage = Property(depends_on='inflows, release') # control attributes inflows = Float(desc='Inflows [hm3]') release = Range(low='min_release', high='max_release') spillage = Property( desc='Spillage [hm3]', depends_on=['storage', 'inflows', 'release'] ) ### Traits view traits_view = View( Group( VGroup(Item('name'), Item('storage'), Item('spillage'), label = 'State', style = 'readonly' ), VGroup(Item('inflows'), Item('release'), label='Control'), ) ) ### Private traits. _storage = Float ### Traits property implementation. def _get_storage(self): new_storage = self._storage - self.release + self.inflows return min(new_storage, self.max_storage) def _set_storage(self, storage_value): self._storage = storage_value def _get_spillage(self): new_storage = self._storage - self.release + self.inflows overflow = new_storage - self.max_storage return max(overflow, 0) def print_state(self): print 'Storage\tRelease\tInflows\tSpillage' str_format = '\t'.join(['{:7.2f}'for i in range(4)]) print str_format.format(self.storage, self.release, self.inflows, self.spillage) print '-' * 79 if __name__ == '__main__': projectA = Reservoir( name = 'Project A', max_storage = 30, max_release = 5, hydraulic_head = 60, efficiency = 0.8 ) state = ReservoirState(reservoir=projectA, storage=25) state.release = 4 state.inflows = 0 state.print_state() state.configure_traits() ``` ![](http://www.scipy-lectures.org/_images/reservoir_state_view.png) Some use cases need the delegation mechanism to be broken by the user when setting the value of the trait. The PrototypeFrom trait implements this behaviour. In?[?]: ``` TraitsUI simplifies the way user interfaces are created. Every trait on a HasTraits class has a default editor that will manage the way the trait is rendered to the screen (e.g. the Range trait is displayed as a slider, etc.). In the very same vein as the Traits declarative way of creating classes, TraitsUI provides a declarative interface to build user interfaces code: ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看