Python實用技巧——類,屬性與裝飾器
規範的編程模式,即使在很小的程序中也能使程序可讀性更高。以一個簡單的電力計算類為例,可以看出Python的類,屬性與裝飾器的一些用法與技巧。
專業背景
LoadCalculation類是用於計算試驗負載(loadbank)參數的。LoadBank是試驗室常用的設備之一,通常由無感電阻器和空心電抗器組成,在開關電器的短路、壽命等試驗中作為負載使用,以保證試驗過程嚴格按照標準規範進行。標準要求的試驗參數一般包括電壓、電流和功率因數,相應的負載參數計算是以歐姆定律為基礎,根據電壓、電流和功率因數參數,計算需要投入的電阻與電感值,從而在理論上滿足試驗要求。
依賴模塊
本程序運行在python3.6.5下,需要導入以下模塊支持
from math import sqrt,pifrom functools import wraps
類的建立
以下為python中定義LoadCalculation類並對其初始化的代碼。
class LoadCalculation: def __init__(self,voltage,current,cosf): """ 負載計算必須初始化輸入電壓、電流與功率因數作為參數 單位分別為V,A :param voltage: :param current: :param cosf: 根據輸入參數計算出 電阻、電抗以及電感值 """ self._voltage=voltage self._current=current self._cosf=cosf self._sinf= self.sinf self._impedance=self.impedance #計算總阻抗,單位歐姆 self._resistance=self.resistance # 電阻的阻抗值,單位歐姆 self._reactance=self.reactance # 電感的感抗值,單位歐姆 self._inductance=self.inductance #電感的電感值,單位 毫亨···為了提高程序的執行效率,我們在類初始化的時候,便對所有需要的參數進行了計算,這些計算後的參數通過屬性的形式將私有變數保存在Python類中。##屬性與裝飾器裝飾器是Python中一個非常好用的功能,簡單而言,是針對函數進行一個外部包裝,以統一實現某種通用的功能。在本類的計算過程中,由於涉及大量浮點運算,保留統一的小數位數非常有必要,利用python內置的round()函數,可以實現指定小數位數的保留,比如round(x,2),為參數x保留2位小數,但是如果在程序中多處都要指定小數位數,那麼就會有許多round函數分散在程序中,如果要求對小數位數進行修改,查找起來很不方便。因此為程序寫一個setround的裝飾器來實現該功能。這個裝飾器內置了accuracy參數,設置默認小數位數為4位,如果在調用裝飾器時需要修改精度,只需要指定accuracy參數即可。```python def setround(func,accuracy=4): """ 裝飾器,用於確定函數返回的浮點值位數,默認保留4位小數 :param func: :return: """ @wraps(func) def wrapper(*args,**kwargs): result=round(func(*args,**kwargs),accuracy) return result return wrapper
除了自己寫的裝飾器外,python也內置了很多現成的裝飾器,property便是其中應用最廣泛的一個,在本類中,我們對各個主要參數均使用了property裝飾器以簡化實現。
@property @setround def sinf(self): #self._sinf=round(sqrt(1-self._cosf**2),4) self._sinf = sqrt(1 - self._cosf ** 2) return self._sinf @property @setround def impedance(self): if self._current!=0: self._impedance=self._voltage/self._current else: self._impedance=-1 return self._impedance @property @setround def resistance(self): if self._impedance!=-1: self._resistance=self._impedance*self._cosf else: self._resistance=-1 return self._resistance @property @setround def reactance(self): if self._impedance!=-1: self._reactance=self._impedance*self.sinf else: self._reactance=-1 return self._reactance @property @setround def inductance(self): if self._impedance!=-1: self._inductance=10*self.reactance/pi else: self._inductance=-1 return self._inductance···## 單元測試由於本類內容較少,採用doctest模塊進行測試,即可滿足要求。測試部分直接寫在類的docstring中。```python """ 用於計算阻抗相關參數的類 #Doctest String >>> load=LoadCalculation(voltage=24,current=100,cosf=0.25) >>> print(load.sinf) 0.9682 >>> print(load.impedance) 0.24 >>> print(load.resistance) 0.06 >>> print(load.reactance) 0.2324 >>> print(load.inductance) 0.7398 """
當然,上述程序只是簡單的負載計算類的建立,在實際的工程應用中,我們在此基礎上建立了完整的負載模型,包括不同電阻的電阻率、載流量、空心電抗器參數等計算,可以根據用戶測試要求,快速生成從理論建模到工程生產需要的各項參數,並根據計算參數進行生產與驗證。
此外,該類還用於對成套負載進行參數計算,結合負載不同檔位與參數值,程序可以快速計算出不同試驗要求下需要投切的負載檔位,在用戶實際使用的過程中,可以根據阻抗自身的特性(主要是迴路和檔位固有功率因數的影響),對計算值進行調節與更新,以便在後續的試驗中能夠更加快速與準確。
所有過程數據保存在sqlite資料庫中。
推薦閱讀: