本文主要介紹了,當使用Python創建自定義類時,如何為其添加屬性,包括為類和實例添加屬性兩種,以及如何獲取自定義的屬性等內容。 ...
摘要:
本文主要介紹了,當使用 Python 創建自定義類時,如何為其添加屬性,包括為類和實例添加屬性兩種,以及如何獲取自定義的屬性等內容。
往期推薦:
全網最適合入門的面向對象編程教程:00 面向對象設計方法導論
全網最適合入門的面向對象編程教程:01 面向對象編程的基本概念
全網最適合入門的面向對象編程教程:02 類和對象的 Python 實現-使用 Python 創建類
更多精彩內容可看:
給你的 Python 加加速:一文速通 Python 並行計算
一個MicroPython的開源項目集錦:awesome-micropython,包含各個方面的Micropython工具庫
文檔和代碼獲取
可訪問如下鏈接進行對文檔下載:
https://github.com/leezisheng/Doc
本文檔主要介紹如何使用 Python 進行面向對象編程,需要讀者對 Python 語法和單片機開發具有基本瞭解。相比其他講解 Python 面向對象編程的博客或書籍而言,本文檔更加詳細、側重於嵌入式上位機應用,以上位機和下位機的常見串口數據收發、數據處理、動態圖繪製等為應用實例,同時使用 Sourcetrail 代碼軟體對代碼進行可視化閱讀便於讀者理解。
相關示例代碼獲取鏈接如下:https://github.com/leezisheng/Python-OOP-Demo
正文
類自身可以具有自己的屬性,被稱為類屬性,或者類成員變數。我們可以通過點標記法在不改動類定義的情況下為實例對象設定任意屬性:
_# 創建一個串口類_
class SerialClass:
pass
_# 生成串口類的實例_
serdev = SerialClass()
_# 添加屬性-串口設備名_
serdev.devport = "COM17"
_# 添加屬性-波特率_
serdev.devbaudrate = 115200
_# 添加屬性-數據位_
serdev.devbytesize = 8
_# 添加屬性-校驗位_
serdev.devparity = 0
_# 添加屬性-停止位_
serdev.devstopbits = 1
_# __dict__可以動態的獲取到對象的全部屬性_
print(serdev.__dict__)
以上代碼創建了一個空的 SerialClass 類,沒有任何數據或行為。然後創建了這個類的兩個實例並分別賦予它們串口設備名、波特率、數據位等串口相關的屬性並賦值。
為對象屬性賦值的語法是 < 對象.< 屬性=< 值 >
這種方法被稱為點標記法(dot notation)。這裡的值可以是任何類型:Python 的基本類型、內置數據類型或者其他的對象,甚至可以是一個函數或另一個類!
最後通過__dict__,就可以動態的獲取到對象的全部屬性,__dict__返回一個字典,屬性名是字典的 key,屬性值是字典的 value。
我們也可以對類屬性賦值,方法同上,代碼如下:
_# 創建一個串口類_
class SerialClass:
pass
_# 添加屬性-串口設備名_
SerialClass.devport = "COM17"
_# 添加屬性-波特率_
SerialClass.devbaudrate = 115200
_# 添加屬性-數據位_
SerialClass.devbytesize = 8
_# 添加屬性-校驗位_
SerialClass.devparity = 0
_# 添加屬性-停止位_
SerialClass.devstopbits = 1
_# __dict__可以動態的獲取到對象的全部屬性_
print(SerialClass.__dict__)
_# 生成串口類的實例_
serdev = SerialClass()
print(serdev.devport)
print(serdev.devbaudrate)
print(serdev.devbytesize)
print(serdev.devparity)
print(serdev.devstopbits)
可以看到,對類屬性賦予新的值,它的所有實例的類屬性也會更新。實際上,類屬性在創建實例時並不會被單獨創建,都是引用的類的屬性,它們在記憶體中只有一份。
同樣我們可以通過實例來改變類屬性,此時將進行拷貝動作,該實例的類屬性將脫離類的屬性,實現了屬性的解綁定,把原來類屬性覆蓋了,該屬性成為了實例的私有屬性,其他實例不會受影響。
serdev.devport = "COM15"
print(serdev.devport)
print(SerialClass.devport)
在實際的使用時,類屬性應該只用於類相關的描述,類示例可以訪問和使用它們,但不應該更改它們。
由於類可以起到模板的作用,因此,可以在創建實例的時候,把一些我們認為必須綁定的屬性強制填寫進去。通過定義一個特殊的__init__方法,在創建實例的時候,就把 devport,devbaudrate 等屬性綁上去:
_# 創建一個串口類_
class SerialClass:
_# 註意:特殊方法“__init__”前後分別有兩個下劃線!!!_
def __init__(self,port,baudrate,bytesize,parity,stopbits):
self.devport = port
self.devbaudrate = baudrate
self.devbytesize = bytesize
self.devparity = parity
self.devstopbits = stopbits
_# 生成串口類的實例_
serdev = SerialClass(port = "COM17",
baudrate = 115200,
bytesize = 8,
parity = 0,
stopbits = 1
)
init 方法的第一個參數永遠是 self,表示創建的實例本身,因此,在 init 方法內部,就可以把各種屬性綁定到 self,因為 self 就指向創建的實例本身。有了 init 方法,在創建實例的時候,就不能傳入空的參數了,必須傳入與 init 方法匹配的參數,但 self 不需要傳,Python 解釋器自己會把實例變數傳進去。