在 Python 中設定類的屬性

Dhruvdeep Singh Saini 2023年1月30日
  1. 在 Python 中使用 setattr() 函式設定類的屬性
  2. 在 Python 中何處使用 Set 屬性
  3. 在 Python 中如何使用 setattr() 為類新增新屬性
  4. 為什麼在類中使用 Set 屬性會導致 Python 中的遞迴
  5. 如何正確使用 Set Attribute 來避免 Python 中的無限遞迴錯誤
  6. 如何修復 MicroPython 中的遞迴錯誤
  7. まとめ
在 Python 中設定類的屬性

Python 的 setattr() 方法來自 PEP383,允許它動態控制和訪問屬性以更改其值。

在 Python 中使用 setattr() 函式設定類的屬性

Python 的 setattr() 函式用於設定類屬性的值。在程式設計中,變數名稱不是靜態的,setattr() 方法非常方便,因為它提供了易用性。

Python 中設定屬性的語法

設定屬性技術可作為利用建構函式和物件方法的替代方法。它可用於在進行屬性分配時通過執行 setattr() 將引數傳遞給屬性。

set 屬性的語法如下。

setattr(self, name, value)

上面的語法指定了以下三件事。

  • self - 你分配其屬性的物件的名稱。
  • name - 分配變數的名稱。
  • value - 分配變數的值。

設定屬性返回 None。請注意,你只能提供字串作為屬性的名稱。

在 Python 中何處使用 Set 屬性

讓我們演示 setattr()baskets 類的用法,並使用 setattr() 方法提供其值。

class Baskets:
    fruit = "Plum"


bas = Baskets()
print("Old fruit: ")
print(bas.fruit)

setattr(bas, "fruit", "Apple")

print("Fruit Now is: ")
print(bas.fruit)

輸出:

Old fruit:
Plum
Fruit Now is:
Apple

Baskets 類有一個水果。setattr() 函式已被呼叫一次以更改籃子的水果。

在 Python 中如何使用 setattr() 為類新增新屬性

如果要向類新增新欄位,可以使用具有相同語法的 setattr() 方法。

setattr() 在現有類中新增一個新變數,並在類中不出現給定變數時設定所述資料。

class Baskets:
    fruit = "Banana"
    vegetable = "Potato"


bas = Baskets()

# Adding candy to the basket
setattr(bas, "candy", "Kit Kat")
print("Added:", bas.candy)

輸出:

Added: Kit Kat

即使我們從上面的程式碼中刪除了一個屬性,我們仍然可以在之後使用 setattr() 新增它。

Python 中設定屬性的不同語法

setattr(object,name,value) 是更短的語法,而不是使用 object.__setattr__(name, value),使兩種方法相同。

object.__setattr__() 在類定義中,並使用 super() 獲取下一個屬性。

上面的語法在兩種情況下無效。

  • 物件已經有一個預定義的字典 __setattr__ 方法,由錯誤引起。
  • 物件的類也有一個 __getattr__(獲取屬性)方法。__getattr__ 方法會阻止所有搜尋,無論屬性是否存在。

為什麼在類中使用 Set 屬性會導致 Python 中的遞迴

目的是在建立成員引數並設定成員引數時呼叫例程時執行程式碼。

對已刪除值和屬性分配的所有更新都會更改例項字典,而不是實際類。

如果在這種情況下已設定例項字典,則直接呼叫 __setattr__ 方法來更新例項字典。

如果你使用以下語法會出現問題:self.name = value __setattr__() 寫入例項變數,因為這將是遞迴操作。它會導致 Python 中的遞迴錯誤。

如何正確使用 Set Attribute 來避免 Python 中的無限遞迴錯誤

有時使用 __setattr__ 會導致編碼錯誤,例如無限遞迴迴圈。

如果你想在定義包含讀寫方法的類時避免使用交錯類,你可以覆蓋 __setattr__ 方法。

但是,如上所述,__init__ 函式可能會導致不必要的遞迴衝突。這是因為 __setattr__ 不斷被呼叫。

class StAttrTest(object):
    def __init__(self, run1):
        self.run1 = run1

    # setattr method with if else
    def __setattr__(self, name, value):

        if name == " Lenn1 ":
            print("Lenn1 test")
        else:
            setattr(self, name, value)


cm = StAttrTest(1)

當你執行上述程式時,此程式碼會執行,但會陷入無休止的遞迴錯誤。

有多種方法可以消除無限迴圈迴圈。

  1. 在類定義中新增 @property 裝飾器,如下所示。
@property
def device(self):
    return self

Python 提供了@property 功能來訪問公共變數等例項變數,同時利用現有的 getter 和 setter 來確認更新的值並防止顯式訪問或資料操作。

  1. 通過刪除 __init__ 方法中的 example 屬性可以快速解決該問題。
class AttrTest(object):
    # init without extra attribute
    def __init__(self):
        self.device = self

上述方法解決了這個問題,但不是一個好的做法,只是一個快速修復。

  1. 也可以直接在 set 屬性方法下使用物件。
object.__setattr__(self, name, value)

MicroPython 有時不接受上述解決方案,因此需要不同的方法。MicroPython 是一種重新實現,力求儘可能保持一致,允許開發人員將程式碼從計算機快速移動到微處理器或整合裝置。

如果你是高階編碼員,你可以按照以下修復設定屬性方法出現的遞迴錯誤。

如何修復 MicroPython 中的遞迴錯誤

此方法涉及使用 object.__dict__ 交替物件的字典值。該技術包括在 __setattr__ 方法中更新物件的字典值。

class StAtrTest(object):
    # setattr with object's dictionary overridden
    def __setattr__(self, name, value):
        print(name, value)
        self.__dict__[name] = value

    def __init__(self, var_O):
        self.var_O = var_O


# Testing
up = StAtrTest(var_O=17)
# Changing
up.var_O = 218

輸出:

var_O 17
var_O 218

這裡描述的方法通常被認為是解決 Python 和 MicroPython 中無限遞迴錯誤的最有效技術。

まとめ

這個內容豐富的指南使用 Python 的 set 屬性方法進行了討論,這是一種在字典例項中寫入屬性和更新類變數以進行簡潔編碼的極好方法。

本文提供了在 Python 中使用 __setattr__ 的各種有效方法,以便你在設計具有讀寫方法的類時不會陷入無限遞迴錯誤。它還強調了 setattr()__setattr__ 方法之間的區別。

請記住,最好和推薦的方法是使用 object.__dict__