規範的程式設計模式,即使在很小的程式中也能使程式可讀性更高。以一個簡單的電力計算類為例,可以看出Python的類,屬性與裝飾器的一些用法與技巧。
專業背景
LoadCalculation類是用于計算試驗負載(loadbank)參數的。LoadBank是試驗室常用的裝置之一,通常由無感電阻器和空心電抗器組成,在開關電器的短路、壽命等試驗中作為負載使用,以保證試驗過程嚴格按照标準規範進行。标準要求的試驗參數一般包括電壓、電流和功率因數,相應的負載參數計算是以歐姆定律為基礎,根據電壓、電流和功率因數參數,計算需要投入的電阻與電感值,進而在理論上滿足試驗要求。
依賴子產品
本程式運作在python3.6.5下,需要導入以下子產品支援
from math import sqrt,pi
from 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資料庫中。