Python中的類和例項屬性
在Python程式語言中,類和例項是面向物件程式設計中最關鍵的兩個概念。類是模板,例項是根據類建立的獨特物件。所有物件的程式相同,但資料可能不同。
在本教程中,我們將學習Python中的類,如何例項化它們,什麼是屬性,以及Python中類屬性和例項屬性的區別。讓我們從定義開始:
什麼是類?
在Python中,類提供了一種將資料和功能捆綁在一起的方法。建立新類會建立一種新型別的物件,允許建立該型別的新的例項。Python中的每個類例項都可以附加屬性來維護其狀態。類例項也可以具有方法(由其類定義)來修改其狀態。
什麼是例項?
物件或例項
Python是一種面向物件的程式語言,它強調物件,即它主要強調函式。在Python中,物件基本上是將資料變數和作用於該資料的方法封裝到單個實體中。Python中幾乎所有東西都是物件,都有其屬性和方法。即使執行“x = 5”,實際上也是從'int'類建立了一個物件。
Python的類屬性是在類中包含的屬性/變數。也就是說,它的作用域在Python類中。
Python中的類屬性只建立單個副本,此單個副本由該特定類中的所有函式和物件共享和使用。
語法
class ClassName: some_string = 'test' # this is a class attribute
對於該類的所有例項,它都將相同。讓我們從此類建立兩個物件,並檢視輸出。
示例
o1 = ClassName() o2 = ClassName() print(ClassName.some_string) print(o1.some_string) print(o2.some_string)
輸出
# test # test # test
正如觀察到的那樣,類屬性在所有從中建立的物件之間是共享的。此外,類屬性可以透過類名.屬性名以及物件.屬性名來訪問。也可以使用類名.屬性名 = '新值'來更改屬性值。
Python的例項屬性是區域性屬性/變數,其作用域在使用該屬性的特定函式中。
每次建立物件時,例項屬性都會建立自己的新副本。實現此行為最常用的函式是__init__()方法。
語法
class SomeClass: def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2
可以將任意數量的屬性傳遞給建構函式。每個物件如何獲得自己的屬性可以透過“self”在建立時引用物件來理解,因此“self”永遠無法直接從類中訪問。
示例
obj1 = SomeClass('test', 10) obj2 = SomeClass('hello', 15) print(obj1.attr1, obj1.attr2) print(obj2.attr1, obj2.attr2)
輸出
# test 10 # hello 15
在這裡我們可以看到每個物件都有其自己的屬性值,並且只有物件本身可以訪問它們。
因此,更改一個物件的屬性不會影響其他物件。
例項屬性使用與類屬性相同的點(.)表示法進行訪問。可以使用物件名.屬性名 = '新值'來更改或重新賦值它們。
更改類屬性值
更改它們的方式可能與更改例項屬性的方式相同,畢竟為什麼不呢?一個字,繼承。
讓我們來看一個示例,在這個示例中,我們定義一個函式,每次呼叫該函式時都會將類屬性的值乘以5。
示例
class ClassA: some_string = 'test' # this is a class attribute class_val = 2 # this is also a class attribute def update(self): ClassA.class_val *= 5 o1 = ClassA() o2 = ClassA() o1.update() print(ClassA.class_val) o2.update() print(ClassA.class_val)
輸出
# 10 # 50
現在讓我們建立一個從該類繼承的新類。
示例
class ClassB(ClassA): pass new_obj = ClassB() print(ClassA.class_val, ClassB.class_val) new_obj.update() print(ClassA.class_val, ClassB.class_val)
輸出
# 50 50 # 250 250
為什麼新類物件可以更改其父類的屬性及其自身的屬性?更重要的是,如何修復它?
我們編寫的內容有兩個主要問題:
ClassB定義中的“pass”關鍵字
以下程式碼:
def update(self): ClassA.class_val *= 5
簡單地放置“pass”意味著ClassB沒有自己的屬性,它只是指向其父類。其次,由於我們的嘗試,我們對類名進行了硬編碼。
此外,呼叫此函式需要先建立一個物件,因為它需要“self”引用。相反,我們可以使用所謂的“類方法”,它具有相同名稱的裝飾器。以下是它應該的樣子:
@classmethod def update(cls): cls.class_val *= 5
它基本上表示我們只想更改從其呼叫的特定類的屬性。讓我們來看一個例子,使事情更清楚。
最後,我們的兩個類應該如下所示:
示例
class OldClass: some_string = 'test' # this is a class attribute class_val = 2 # this is also a class attribute @classmethod def update(cls): cls.class_val *= 5 class NewClass(OldClass): class_val = 2 # this is different from the parent class
現在是時候分別從兩個類呼叫更新函數了。
print("Initially:", OldClass.class_val, NewClass.class_val) OldClass.update() print("After calling update on old class once:", OldClass.class_val, NewClass.class_val) NewClass.update() NewClass.update() print("After calling update on new class twice:", OldClass.class_val, NewClass.class_val)
輸出
# Initially: 2 2 # After calling update on old class once: 10 2 # After calling update on new class twice: 10 50
因此,現在我們可以更改Python中的類屬性而無需建立物件,即使在從父類繼承之後,類方法也會知道要更改哪個類的屬性。
資料結構
網路
關係資料庫管理系統(RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP