1. 程式人生 > >[Python] 面向物件程式設計進階(一):控制屬性的三種方式

[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學習筆記13Python面向物件程式設計

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