[Python] 面向物件程式設計進階(一):控制屬性的三種方式
[email protected]裝飾器
在文章Python面向物件程式設計及Property裝飾器中,通過@property裝飾器可以代替Python類的getter/setter方法,實現對私有屬性的訪問,在這裡對屬性相關的其他內容進行總結歸納。
2.__slots__
使用
先定義簡單的一個類:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
由於Python是可以動態繫結屬性和方法的,因此,可以對一個類或者類例項繫結一個屬性。如果對一個物件繫結一個屬性,該屬性只對當前物件起作用,類的其他物件是沒有這個屬性的,如:
if __name__ == "__main__":
stu1 = Student("ZhangSan",24)
# 對stu1物件繫結一個nickname屬性
stu1.nickname = "little Zhang"
stu2 = Student("Lisi",24)
print(stu1.nickname) # little Zhang
# stu2沒有nickname屬性,因此出現異常
# print(stu2.nickname) # 'Student' object has no attribute 'nickname'
print(stu1.nickname) # little Zhang
print(stu2.nickname) # 'Student' object has no attribute 'nickname'
在建立類時(如果沒有使用__slots__
屬性),python會為每個例項建立一個__dict__
屬性,以字典的形式存放每個例項的屬性,我們分別列印stu1和stu2的__dict__
屬性:
print(stu1.__dict__)
print(stu1.__dict__)
'''
輸出結果:
#{'nickname': 'little Zhang', 'age': 24, 'name': 'ZhangSan'}
{'nickname': 'Lisi', 'age': 23}
'''
如果要對類的所有物件都繫結一個屬性,那麼就要繫結在類上:
Student.nickname = "litter Student"
這時stu1和stu2都具有nickname屬性了。
如果禁止對類進行屬性的新增和刪除,就要在定義類時定義一個特殊的__slots__
屬性即可,這樣的類建立後將包含指定的元素,而沒有__dict__
屬性,如下面的NewStudent類:
class NewStudent:
__slots__ = ("name", "age")
def __init__(self, name, age):
self.name = name
self.age = age
if __name__ == "__main__":
stu1 = NewStudent("ZhangSan",24)
# 由於使用__slot__指定了屬性,不能再進行繫結,出現AttributeError
stu1.nickname = "little Zhang" # AttributeError: 'NewStudent' object has no attribute 'nickname'
# 沒有__dict__屬性,出現AttributeError
print("dict:", stu1.__dict__) # AttributeError: 'NewStudent' object has no attribute '__dict__'
注意:使用
__slots__
要注意,__slots__
定義的屬性僅對當前類例項起作用,對繼承的子類是不起作用的。
3.屬性相關的特殊方法
通過@property裝飾器可以快速簡單的對屬性進行控制,但是可讀性差 ,因此,除這種方式外,可以使用python內建的一些特殊方法來控制屬性的存取,這些方法見下表:
特殊方法 | 使用 | 描述 |
---|---|---|
__getattr__(self,item) |
v = obj.n | 返回obj物件的item屬性 |
__setattr__(self, key, value) |
obj.key = value | 將obj物件的key屬性設定為value |
__delattr__(self,item) |
v = obj.n | 刪除obj物件的item屬性 |
__dir__(self) |
dir(obj) | 返回obj物件的屬性列表 |
__getattribute__(self,item) |
v = obj.n | 返回obj物件的item屬性 |
例如通過上述方法對Student類中name屬性進行控制:
def __setattr__(self, key, value):
if key == "name":
if not isinstance(value, str):
raise AttributeError("from setarrt:name must be s str obj")
self.__name = value
如果類中同時定義了__setattr__()
和@name.setter,執行哪一個呢?肯定是前者了.
注意:如果要實現這些方法來對屬性存取進行控制,應該做好條件判斷,在設定的屬性或值不符合時丟擲AttributeError或ValueError。
__getattribute__()
和__getattr__()
方法都用於獲取屬性,在尋找屬性時,其中如果實現了,則__getattr__()
不會呼叫。並且__getattribute__()
通常會導致遞迴呼叫,因此一般不需要實現該方法。
相關推薦
[Python] 面向物件程式設計進階(一):控制屬性的三種方式
[email protected]裝飾器 在文章Python面向物件程式設計及Property裝飾器中,通過@property裝飾器可以代替Python類的getter/setter方法,實現對私有屬性的訪問,在這裡對屬性相關的其他內容進行總結歸納。
Python 面向對象進階(一)
使用 www. import ins 遍歷 number 組成 之前 叠代 1. 生成器 通過列表生成式,可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個 包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那
面向物件程式設計進階
python內建函式 isinstance(obj,class) 判斷一個物件是否是已知的型別,類似type() isinstance語法:isinstance(object,classinfo) object 是例項/物件 classinfo 可以是直接或間接類名
python 面向物件(進階篇)
本篇將詳細介紹Python 類的成員、成員修飾符、類的特殊成員。 類的成員 類的成員可以分為三大類:欄位、方法和屬性 注:所有成員中,只有普通欄位的內容儲存物件中,即:根據此類建立了多少物件,在記憶體中就有多少個普通欄位。而其他的成員,則都是儲存在類中,即:無論物件
面向物件程式設計進階——設計模式 design patterns
前言 設計模式(design pattern)是一套被反覆使用、多數人知曉、經過分類編目的優秀程式碼設計經驗的總結。關鍵詞:重用程式碼、工程化、面向物件。設計模式起源於建築設計學,最先由 Gang of Four 提升到了理論高度。 可複用面向物件體系分為
面向物件程式設計進階---介面
介面 介面是另一種定義資料型別的方式。它和類非常相似的。 相同之處:都有成員變數和成員方法 也可以形成繼承關係 不同之處:介面中的屬性都是常量(final) 介面中的方法是抽象方法(沒有方法體) 引入介面的原因:Java只支援單重繼承,每個類只能有一個超類
Python開發【第七篇】:面向物件(進階篇)
上一篇《Python 面向物件(初級篇)》文章介紹了面向物件基本知識: 面向物件是一種程式設計方式,此程式設計方式的實現是基於對 類 和 物件 的使用 類 是一個模板,模板中包裝了多個“函式”供使用(可以講多函式中公用的變數封裝到物件中) 物件,根據模板
Python學習之旅—面向對象進階知識:類的命名空間,類的組合與繼承
ati error role ont 之前 obj say 報錯 抽象 前言 上篇博客筆者帶領大家初步梳理了Python面向對象的基礎知識,本篇博客將專註於解決三個知識點:類的命名空間,類的組合以及面向對象的三大特性之一繼承,一起跟隨筆者老看看今天的內容吧。 1.
python 面向物件程式設計:類和例項
深度學習在構建網路模型時,看到用類來構建一個模型例項,清晰明瞭,所以這篇博文主要學習一下python類 類和例項: 類可以起到模板的作用,因此,可以在建立例項的時候,把一些我們認為必須繫結的屬性強制填寫進去。通過定義一個特殊的__init__(注意:特殊方法“__init__”前後分別有
python之面向物件高階進階-反射與內建模組
內建函式模組isinstance和issubaclassclass Foo: pass obj=Foo() print(isinstance(obj,Foo)) #isinstance(obj,Foo)判斷是否obj是否是類 Foo 的物件class Pa
Python學習筆記13:Python面向物件程式設計
1、引言 (1)類和例項:類是物件的定義,例項是“真正的實物”。 定義類:類名通常大寫字母打頭。 class MyNewObjectType(bases): 'define MyNewObjectType class' class_su
python面向物件程式設計例項:飛機大戰
說明:此則部落格只是自己學習python程式設計的學習記錄,其中完成的程式設計只是飛機大戰的小小小demo,只為自己熟悉python語言和pygame,所以程式並不完善,只當練手和記錄,當然可基於次程式進行後續的完善開發。最後感謝一下hm的python教程。至於程式中的圖片
python面向對象進階
參數 tar pri 析構 getattr 實例初始化 pan bsp clas isinstance(obj,cls)檢查是否obj是否是類 cls 的對象。 isinstance(obj,cls)檢查是否obj是否是類 cls 的對象。 反射 python面向對象中的反
java 進階一:代理和動態代理
實現 public rgs tostring 開源項目 body llb ack code 靜態代理: 定義頂級接口:Iservice //目標類和代理類都實現該接口 public interface Iservice { public String serv
Python 面向對象進階(二)
否則 垃圾回收 進階 所有 不重復 發生 rom 指定 hello 1. 垃圾回收 小整數對象池 Python對小整數的定義是 [-5, 257),這些整數對象是提前建立好的; 在一個Python程序中,所有位於這個範圍內的整數,使用的都是同一個對象; 單個字符共用對象
python 面向對象(進階篇)
property 命名 int col code call ssm 有一種 信息 類的成員 字段 普通字段 保存在對象當中,執行只能通過對象訪問 靜態字段 保存在類當中, 執行可以通過類訪問也可以通過對象訪問 方法 普通方法 保存在類當中,由對象來調用 靜態
面向對象進階6:元類
ise and 否則 tag weak wal 方法 pan strong 六 練習題 練習一:在元類中控制把自定義類的數據屬性都變成大寫 class Mymetaclass(type): def __new__(cls,name,bases,attrs):
python------面向對象進階反射詳解(重點)
code one -- ... set bject pan strip() asa 一.反射 通過字符串映射或者修改程序運行時的狀態,屬性,或者方法。 1.getattr(object,name,default=None) 2.hasattr(object,name
python------面向對象進階 Socket網絡編程
系統 組織 com bubuko 一個 types http pen pytho 一.Socket網絡編程 1.七層模型,亦稱OSI(Open System Interconnection)參考模型,是參考模型是國際標準化組織(ISO)制定的一個用於計算機或通信系統間互聯的
Xadmin進階一:如何增加一列
init 9.png pla plugin cto object 實現 list 下標 主要實現參考 relate.py插件,通過繼承BaseAdminPlugin實現,實現效果: 主要的的代碼如下: from xadmin.views import BaseAdminP