你能告訴我在方法內部呼叫 Class_name.class_variable 和 self.class_variable 有什么區別嗎?這是示例:
class Employee:
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
def apply_raise(self):
self.pay = int(self.pay * Employee.raise_amount)
所以我使用了一個Employee.raise_amount,但我也可以這樣寫這個方法:
def apply_raise(self):
self.pay = int(self.pay * self.raise_amount)
我用以下方法進行了測驗:
emp_1 = Employee('James', 'Amb', 10000)
emp_2 = Employee('Test', 'User', 20000)
print("Original value")
print("emp_1.raise_amount", emp_1.raise_amount)
print("emp_2.raise_amount", emp_2.raise_amount)
emp_1.raise_amount = 1.1
print("emp_1.raise_amount = 1.1")
print("emp_1.raise_amount", emp_1.raise_amount)
print("emp_2.raise_amount", emp_2.raise_amount)
Employee.raise_amount = 1.2
print("Employee.raise_amount = 1.2")
print("emp_1.raise_amount", emp_1.raise_amount)
print("emp_2.raise_amount", emp_2.raise_amount)
我使用 Employee.raise_amount 運行程式,然后使用 self.raise_amount。在這兩種情況下 OUTPUT 是相同的:
Original value
emp_1.raise_amount 1.04
emp_2.raise_amount 1.04
emp_1.raise_amount = 1.1
emp_1.raise_amount 1.1
emp_2.raise_amount 1.04
Employee.raise_amount = 1.2
emp_1.raise_amount 1.1
emp_2.raise_amount 1.2
那么有什么區別,我什么時候應該使用 Class_name.class_variable 和 self.class_variable
uj5u.com熱心網友回復:
Python 屬性讀取,self.attribute
作業方式如下:
- Python檢查屬性是否是類或祖先類中的資料描述符,如果是,
__get__
則呼叫其方法(不是這種情況,我稍后會回到這里) - 然后檢查實體(self)
__dict__
屬性,并查看它是否包含attribute
,如果是,則獲取 - 檢查是否存在“非資料描述符”(沒有
__set__
方法的描述符,例如函式或方法) - 然后檢查它是否是類中的普通(非描述符)屬性
__dict__
<-你在這里! - 檢查任何祖先類中的普通屬性
- 呼叫
__gettattr__
類上的方法(如果存在) - 引發屬性錯誤。
在使用語言時,這套規則實際上是相當自然的。但是你必須小心,如果你在任何時候寫回屬性 - 如果你做類似的事情self.attribute = value
,那么屬性是在實體中設定的,而不是在類上,如果在其他方法中你正在通過這樣做來檢索ClassName.attribute
它將看到在類上設定的原始值,而不是在 上設定的值self
,即使它是同一個實體。
考慮到所有因素,總是使用的自然設計self.attribute
將更好地用于只讀類屬性。如果您需要單個實體的特殊值,您可以只為該實體設定一個新值,一切都會繼續作業。對于使用您的案例的示例,假設對于大多數員工來說,raise_ammount 是 1.04,但其中一個特殊情況下為 1.06,任何方法甚至外部代碼都可以在實體上設定新屬性,以及讀取該值的方法fromself.
將查看更新的數字。
至于“描述符” - 它們是系結到具有或方法之一__get__
的類的特殊物件,并覆寫實體和類的屬性訪問。它們是裝飾器以及方法和類方法本身使用的機制(以便語言可以在方法呼叫中插入引數)。__set__
__delete__
@property
self
哦,所有這些步驟都以object.__getattribute__
方法中的語言編碼(與 不同__getattr__
)。任何覆寫的類都__getattribute__
可以隨意重寫這些規則(通常一個人只會調整對某些屬性的訪問,以創建代理物件或類似的東西,不會產生幾乎一樣復雜的完整分層規則集)
uj5u.com熱心網友回復:
一個很適合繼承,另一個則不行。
class Base:
a = 1
def f(self):
print(Base.a)
class Foo(Base):
a = 2
Base().f()
Foo().f()
輸出
1
1
更改print(Base.a)
為print(self.a)
將輸出更改為
1
2
因為 nowself
是Foo
(所以它指的是Foo.a
)的一個實體,其中Base.a
毫無疑問地指的是Base.a
,而不管我們用來呼叫的當前實體是什么f
。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/478554.html