AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

Python屬性自省:深入了解屬性訪問與限制

來源: 責編: 時間:2023-09-22 20:12:41 356觀看
導讀在Python中,屬性自省是一種強大的特性,它允許我們在運行時檢查和操作對象的屬性。在本文中,我們將探討Python中的屬性自省,并結合實際場景和代碼來展示其用法。1. 私有屬性與訪問限制Python中的私有屬性是指以下劃線開頭

在Python中,屬性自省是一種強大的特性,它允許我們在運行時檢查和操作對象的屬性。在本文中,我們將探討Python中的屬性自省,并結合實際場景和代碼來展示其用法。5Ds28資訊網——每日最新資訊28at.com

5Ds28資訊網——每日最新資訊28at.com

1. 私有屬性與訪問限制

Python中的私有屬性是指以下劃線開頭的變量或方法,例如 _name 或 _method()。盡管這種命名約定并非強制性的,只是一種慣例,但它用于提示該屬性或方法應該只在類內部使用,而不應該在外部直接訪問。5Ds28資訊網——每日最新資訊28at.com

Python中的私有屬性具有以下特點:5Ds28資訊網——每日最新資訊28at.com

  • 私有屬性不能被外部直接訪問,但可以通過類內部的方法間接地訪問。
  • 在類內部定義的方法可以訪問所有屬性,包括私有屬性,因為它們都在同一個作用域內。
  • 子類無法繼承父類的私有屬性,但可以通過公有方法來訪問父類的私有屬性。

接下來勇哥帶你探討如何訪問和修改私有屬性:5Ds28資訊網——每日最新資訊28at.com

class YongeGe:    name= '勇哥' # 普通屬性    _ager = 100   # 普通屬性    __money = 109  # 私有屬性    __money_empty__ = 1  # 不推薦做法yongge = YongeGe()print(yongge .name)  # 輸出: 勇哥print(yongge ._ager )  # 輸出: 100print(yongge ._YongeGe__money )  # 輸出: 109  print(yongge .__money_empty__ )  # 輸出: 1print(yongge .__money )  # 輸出: AttributeError: 'YongeGe' object has no attribute '__money'

很明顯看到 Python 中沒有真正的私有屬性,實際上雙下劃線開頭的屬性被名稱重整了,即將屬性名轉換為 _ClassName__name的形式,使其難以在外部被訪問。通過_YongGe__money可以間接訪問私有屬性__money 。但是一般不要用,就比如你爹告訴你剩100塊了,要省點花,你非要點個海底撈一把梭哈!5Ds28資訊網——每日最新資訊28at.com

總之,Python的私有屬性機制主要基于命名約定,其作用是限制屬性的可見性和訪問性,從而提高代碼的封裝性和安全性。然而,需要注意的是,這種機制只是一種建議性的規范,并不能完全避免私有屬性被訪問的可能性。5Ds28資訊網——每日最新資訊28at.com

2. 屬性自省與對象內部狀態查看

在實際開發中,我們經常需要查看對象的屬性和方法,以便理解其內部狀態。Python提供了幾種屬性自省的方法,使我們能夠方便地檢查對象的屬性。5Ds28資訊網——每日最新資訊28at.com

(1) 使用__dict__屬性

__dict__是對象的一個屬性,它包含了對象的所有屬性和方法。通過訪問__dict__,我們可以查看對象的內部狀態。5Ds28資訊網——每日最新資訊28at.com

例如,我們定義了一個名為Person的類,其中包含name和age兩個屬性,以及一個say_hello方法。下面的代碼展示了如何通過訪問__dict__來查看對象的屬性和方法:5Ds28資訊網——每日最新資訊28at.com

class YongeGe:    def __init__(self, name, money):        self.name = name        self.money= money    def money(self):        print(f"Hello, my name is {self.name}.I have {self.money} dollar ")yongge = YongeGe("勇哥", "10")yongge .money= "1010"yongge .__dict__["age"] = "18"

輸出結果為:5Ds28資訊網——每日最新資訊28at.com

{'name': '勇哥', 'money': '1010', 'age': '18'}

我們可以看到對象yongge的屬性和方法,包括name、age、money以及money方法。5Ds28資訊網——每日最新資訊28at.com

需要注意的是,實例對象的__dict__屬性只能訪問和修改其自身的屬性和方法,而無法訪問其所屬類的屬性和方法。如果需要訪問類的屬性和方法,可以通過類的__dict__屬性來實現。5Ds28資訊網——每日最新資訊28at.com

例如,我們可以通過訪問Person.__dict__來查看類Person的所有屬性和方法:5Ds28資訊網——每日最新資訊28at.com

print(yongge .__dict__)

輸出結果為:5Ds28資訊網——每日最新資訊28at.com

{'__module__': '__main__', '__init__': <function YongeGe.__init__ at 0x0000017E50B9C5E0>, 'money': <function YongeGe.money at 0x0000017E50BBADC0>, '__dict__': <attribute '__dict__' of 'YongeGe' objects>, '__weakref__': <attribute '__weakref__' of 'YongeGe' objects>, '__doc__': None}

上述輸出結果中,除了__init__、say_hello和__dict__之外,還包括其他一些特殊屬性和方法。通過查看類的__dict__,我們可以獲取到類的所有成員。5Ds28資訊網——每日最新資訊28at.com

(2) 使用dir()函數

除了訪問對象的__dict__屬性外,我們還可以使用dir()函數來查看對象的屬性和方法。5Ds28資訊網——每日最新資訊28at.com

dir()函數返回一個包含對象所有屬性和方法名稱的列表。它不僅可以用于普通對象,還可以用于模塊、類和內置類型等。5Ds28資訊網——每日最新資訊28at.com

例如,下面的代碼展示了如何使用dir()函數查看對象的屬性和方法:5Ds28資訊網——每日最新資訊28at.com

print(dir(p1))

輸出結果為:5Ds28資訊網——每日最新資訊28at.com

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'hometown', 'name', 'say_hello']

從輸出結果中,我們可以看到對象p1的屬性和方法的名稱列表。5Ds28資訊網——每日最新資訊28at.com

(3) 使用__slots__ 屬性

在默認情況下,Python 類的實例會使用一個字典來存儲它們的屬性。這種方式對于屬性很少的對象來說可能會浪費空間。特別是在創建大量實例時,這種空間消耗會變得更明顯。5Ds28資訊網——每日最新資訊28at.com

為了解決這個問題,我們可以通過在類定義中使用__slots__來覆蓋默認的__dict__行為。slots__是一個特殊屬性,它接受一個屬性名稱的序列,并且在每個實例中只為這些屬性保留足夠的空間來存儲屬性值。因為沒有為每個實例創建__dict,所以可以節省空間。5Ds28資訊網——每日最新資訊28at.com

class YongeGe:    # 定義 __slots__屬性,讓類實例只能綁定 __slots__中指定的屬性,且不能添加其他屬性    __slots__ = ('name', 'money')    def __init__(self, name_, money_):        self.name = name_        self.money = money_if __name__ == '__main__':    yongge = YongeGe('勇哥', 100)    print(yongge.name)     setattr(yongge, 'new_attr', 100) # 輸出:AttributeError: 'YongeGe' object has no attribute 'new_attr'

從上面的代碼可以看到,在類中綁定了__slots__后,會限制類實例的靈活性,不能動態添加新的屬性,所以在使用這玩意的時候,要仔細想想要靈活還是要內存?5Ds28資訊網——每日最新資訊28at.com

(4) 自定義屬性訪問5Ds28資訊網——每日最新資訊28at.com

還可以通過定義一些特殊方法來自定義類實例的屬性訪問行為。這些特殊方法可以控制屬性的獲取、設置和刪除操作。5Ds28資訊網——每日最新資訊28at.com

  • __getattribute__ 方法:獲取一個屬性時,Python 會首先調用該方法。我們可以在這個方法中自定義屬性的獲取行為。例如,可以在方法中檢查屬性是否存在,并返回相應的值。
def __getattribute__(self, data):    value = super().__getattribute__(data)    return value
  • setattr 方法:設置一個屬性時,Python 會調用該方法。我們可以在這個方法中自定義屬性的設置行為。例如,可以在方法中對屬性進行類型檢查,然后使用 super().setattr() 方法設置屬性的值。 
def __setattr__(self, key, value):    super().__setattr__(key, value)
  • __delattr__ 方法:刪除一個屬性時,Python 會調用該方法。我們可以在這個方法中自定義屬性的刪除行為。例如,可以在方法中執行一些清理操作或拋出異常。
def __delattr__(self, item):    super().__delattr__(item)
  • __getattr__ 方法:獲取一個不存在的屬性時,Python 會調用該方法。我們可以在這個方法中自定義對不存在屬性的處理邏輯。例如,可以返回默認值或者拋出異常。
def __getattr__(self, item):    pass

以上是一些常用的自定義屬性訪問的方法。瞧瞧下面語句的執行順序:5Ds28資訊網——每日最新資訊28at.com

class MyClass:    def __init__(self):        self._data = {}    def __getattribute__(self, name):        # 自定義獲取屬性的行為        if name == 'attribute1':            return 'Custom Value'        elif name == 'attribute2':            return self._data[name]  # 注意,這里會繼續執行一次 __getattribute__        else:            return super().__getattribute__(name)    def __setattr__(self, name, value):        # 自定義設置屬性的行為        if name == 'attribute2':            print("__setattr__", name, value)            self._data[name] = value + 10        else:            super().__setattr__(name, value)    def __delattr__(self, name):        # 自定義刪除屬性的行為        if name == 'attribute3':            self._data.pop(name, None)        else:            super().__delattr__(name)    def __getattr__(self, name):        # 處理不存在的屬性        return f'Attribute "{name}" does not exist.'if __name__ == '__main__':    obj = MyClass()    obj.attribute2 = 5    res = obj.attribute2    print(res)  # 輸出: __setattr__ attribute2 5 ;15    print(obj.attribute1)  # 輸出: Custom Value    del obj.attribute3    print(obj.attribute3)  # 輸出: Attribute "attribute3" does not exist.

在上面的示例中,我們創建了一個名為 MyClass 的類,其中定義了 __getattribute__、__setattr__、5Ds28資訊網——每日最新資訊28at.com

__delattr__ 和 __getattr__ 四個方法來自定義屬性訪問行為。通過在這些方法中編寫相應的邏輯,我們可以控制屬性的獲取、設置和刪除操作,從而實現自定義的屬性訪問行為。5Ds28資訊網——每日最新資訊28at.com

通過自定義屬性訪問,我們可以更靈活地控制類實例的屬性操作,滿足特定的需求,并增強代碼的可讀性和可維護性。5Ds28資訊網——每日最新資訊28at.com

(5) 使用getattr()、setattr()和hasattr()函數5Ds28資訊網——每日最新資訊28at.com

除了查看對象的屬性和方法外,我們還可以使用getattr()、setattr()和hasattr()函數來動態地訪問和修改對象的屬性。5Ds28資訊網——每日最新資訊28at.com

  • getattr(obj, attr)函數用于獲取對象obj的屬性attr的值。
  • setattr(obj, attr, value)函數用于設置對象obj的屬性attr的值為value。
  • hasattr(obj, attr)函數用于檢查對象obj是否具有屬性attr,如果有返回True,否則返回False。

這些函數提供了一種靈活的方式來操作對象的屬性,特別適用于需要在運行時根據條件訪問或修改屬性的情況。5Ds28資訊網——每日最新資訊28at.com

例如,我們可以通過調用getattr()函數來獲取對象的屬性值:5Ds28資訊網——每日最新資訊28at.com

name_value = getattr(yongge, "name")print(name_value)

輸出結果為:5Ds28資訊網——每日最新資訊28at.com

勇哥

上述代碼中,我們使用getattr(yongge, "name")來獲取對象p1的name屬性的值。5Ds28資訊網——每日最新資訊28at.com

類似地,我們可以使用setattr()函數來設置對象的屬性值:5Ds28資訊網——每日最新資訊28at.com

setattr(yongge, "age", 40)print(yongge.age)

輸出結果為:5Ds28資訊網——每日最新資訊28at.com

40

上述代碼中,我們使用setattr(yongge, "age", 40)將對象yongge的age屬性值設置為30,然后再次打印yongge.age,可以看到屬性值已被修改。5Ds28資訊網——每日最新資訊28at.com

另外,我們還可以使用hasattr()函數來檢查對象是否具有某個屬性:5Ds28資訊網——每日最新資訊28at.com

has_money = hasattr(yongge, "money")print(has_money)

輸出結果為:5Ds28資訊網——每日最新資訊28at.com

True

使用hasattr(yongge, "money")檢查對象yongge是否具有money屬性,結果為True,說明對象具有該屬性。5Ds28資訊網——每日最新資訊28at.com

通過上述幾種方法,我們可以方便地進行屬性自省,查看和修改對象的屬性,從而更好地理解和操作代碼。5Ds28資訊網——每日最新資訊28at.com

3. 來點實際場景

假設我們正在開發一個電商網站,需要處理用戶購物車的相關邏輯。購物車中的商品信息以字典的形式存儲在用戶對象的屬性中。我們需要編寫一個函數,用于計算購物車中商品的總價值。5Ds28資訊網——每日最新資訊28at.com

定義一個User類,包含一個cart屬性用于存儲購物車中的商品信息:5Ds28資訊網——每日最新資訊28at.com

class User:    def __init__(self, name):        self.name = name        self.cart = {}    def add_to_cart(self, item, price):        self.cart[item] = price

定義一個calculate_cart_value()函數,用于計算購物車中商品的總價值。在函數內部,我們可以通過屬性自省來獲取購物車中的商品信息,并計算總價值:5Ds28資訊網——每日最新資訊28at.com

def calculate_cart_value(user):    cart = user.__dict__.get("cart", {})    total_value = sum(cart.values())    return total_value

在上述代碼中,我們使用user.__dict__.get("cart", {})來獲取購物車信息,如果用戶對象中不存在cart屬性,則返回一個空字典。然后,我們使用sum(cart.values())來計算購物車中商品價格的總和。5Ds28資訊網——每日最新資訊28at.com

下面是使用上述代碼的示例:5Ds28資訊網——每日最新資訊28at.com

# 創建用戶對象user = User("勇哥")# 添加商品到購物車user.add_to_cart("apple", 10)user.add_to_cart("banana", 5)user.add_to_cart("orange", 8)# 計算購物車總價值total_value = calculate_cart_value(user)print(total_value)  # 輸出: 23

通過使用屬性自省,我們可以方便地訪問購物車信息,并計算總價值。屬性自省還是挺重要的,面試也問得多,實在不會用也要背好飛機大炮的制作流程。但是這個玩意也不要濫用喲,頻繁動態訪問,會有一定的性能開銷喲~5Ds28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-11214-0.htmlPython屬性自省:深入了解屬性訪問與限制

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C/C++中如何不使用額外的中間變量交換兩個變量的值

下一篇: 中文文本處理高手指南:從零到高手掌握Python中jieba庫

標簽:
  • 熱門焦點
  • K60至尊版剛預熱 一加Ace2 Pro正面硬剛

    Redmi這邊剛如火如荼的宣傳了K60 Ultra的各種技術和硬件配置,作為競品的一加也坐不住了。一加中國區總裁李杰發布了兩條微博,表示在自家的一加Ace2上早就已經采用了和PixelWo
  • 6月安卓手機性能榜:vivo/iQOO霸占旗艦排行榜前三

    2023年上半年已經正式過去了,我們也迎來了安兔兔V10版本,在新的驍龍8Gen3和天璣9300發布之前,性能榜的榜單大體會以驍龍8Gen2和天璣9200+為主,至于那顆3.36GHz的驍龍8Gen2領先
  • 帥氣純真少年!日本最帥初中生選美冠軍出爐

    日本第一帥哥初一生選美大賽冠軍現已正式出爐,冠軍是來自千葉縣的宗田悠良。日本一直熱衷于各種選美大賽,從&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 分布式系統中的CAP理論,面試必問,你理解了嘛?

    對于剛剛接觸分布式系統的小伙伴們來說,一提起分布式系統,就感覺高大上,深不可測。而且看了很多書和視頻還是一臉懵逼。這篇文章主要使用大白話的方式,帶你理解一下分布式系統
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人員可能會涉及各種各樣的安全任務,包括但不限于:開發某些安全工具的插件,滿足自己特定的安全需求;自定義github搜索工具,快速查找所需的安全資料、漏洞poc、exp
  • 10天營收超1億美元,《星鐵》比《原神》差在哪?

    來源:伯虎財經作者:陳平安即便你沒玩過《原神》,你一定聽說過的它的大名。恨它的人把《原神》開服那天稱作是中國游戲史上最黑暗的一天,有粉絲因為索尼在PS平臺上線《原神》,怒而
  • 消息稱小米汽車開始篩選交付中心:需至少120個車位

    IT之家 7 月 7 日消息,日前,有微博簡介為“汽車行業從業者、長三角一體化擁護者”的微博用戶 @長三角行健者 發文表示,據經銷商集團反饋,小米汽車目前
  • 2納米決戰2025

    集微網報道 從三強爭霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來。無論是老牌勁旅臺積電、三星,還是誓言重回先進制程領先地位的英特爾,甚至初成立不久的新
  • 到手價3099元起!iQOO Neo8 Pro今日首銷:安卓性能最強旗艦

    5月23日,iQOO如期舉行了新品發布會,全新的iQOO Neo8系列也正式與大家見面,包含iQOO Neo8和iQOO Neo8 Pro兩個版本,其中標準版搭載高通驍龍8+,而Pro版更
Top