知識點:
- 類屬性與實例屬性;
- 類方法與實例方法;
- 靜態方法;
類屬性與實例屬性
類屬性與實例屬性的區別
-
屬性的綁定不同
- 類屬性與當前類相關(綁定的是當前類),與當前類創建的任何對象無關;
- 實例屬性與當前對象相關(綁定的是當前對象);
-
訪問方式不同
- 對於類屬性,可以通過類名,進行訪問,也可以通過對象進行訪問。但是,通過對象進行訪問,屬於“只讀訪問”,我們不能對其進行修改;
- 對於實例屬性,只能通過創建的對象,進行訪問,不能通過類名進行訪問;
什么時候定義類屬性?什么時候定義實例屬性呢?
- ① 定義類屬性
不同對象都一致(完全一樣)的屬性,定義為"類屬性",被大家共享。像desc = "人的描述",只有一個。
- ② 定義實例屬性
不同對象都不一樣的屬性,定義為"實例屬性",被個人獨享。像name,age,不同對象一般是不同的。
再次提醒:實例屬性定義在init方法中,是不同對象所獨享;類屬性定義在類中,能被不同對象共享。
下面來看一個案例:
class Person:
# 類屬性
desc = "人的描述"
def __init__(self, name, age):
# 實例屬性
self.name = name
self.age = age
p = Person("梁同學", 18)
訪問類屬性
強烈建議,類屬性總是通過類名去訪問。
① 通過類名
- 訪問類屬性(可以修改類屬性)
- 修改類屬性(可以修改成功)
② 通過對象
- 訪問類屬性(只能是只讀模式訪問,不能通過對象修改類屬性)
- 修改類屬性,修改時不會報錯,但是並沒有真正修改成功。
通過對象修改類屬性,其實並不是修改類屬性,而是動態地給對象p增加了一個屬性desc,只不過這個屬性名desc,和類屬性desc,具有相同的名稱而已。
訪問實例屬性
實例屬性只能夠通過,創建的對象,進行訪問。
class Person:
# 類屬性
desc = "人的描述"
def __init__(self, name, age):
# 實例屬性
self.name = name
self.age = age
p = Person("梁同學", 18)
① 通過對象,訪問實例屬性
② 通過類名,訪問實例屬性,會報錯
類屬性與實例屬性 知識總結
實例屬性: 實例屬性是對象獨享的,每個對象都有自己的實例屬性,彼此之間不受干擾。某個對象改變了自身的實例屬性,對其他對象不會造成影響。
類屬性: 類屬性為類所有。由所有對象所共享(不屬於任何對象)。一旦類屬性發生了改變,會影響到所有對象。
類方法與實例方法
類方法與實例方法的相關解釋
我們先來看一個例子:
class Person:
# 實例方法
def walk(self):
print("走路")
# 類方法,使用@classmethod修飾
# 類方法的第一個參數是固定的。根據慣例,將其命名為cls。但這也不是必須的。
@classmethod
def cm(cls):
# cls就是Person
print("這是類方法")
print(cls is Person)
p = Person()
觀察上述例子,對於類方法,有下面幾點需要注意:
- 注意1 :類方法,使用@classmethod修飾;
- 注意2 :類方法的第一個參數是固定的。根據慣例,將其命名為cls;
- 注意3 :cls就是Person;
- 注意4 :類方法的第一個參數會隱式傳遞,無需我們顯式傳遞;
訪問類方法
有兩種方法可以訪問類方法。但是強烈建議,類方法通過類名來訪問。
① 通過類名訪問類方法
② 通過對象訪問類方法
訪問實例方法
實例方法只能通過對象訪問,而不能通過類名訪問。
① 通過對象訪問實例方法
② 通過類名訪問實例方法,會報錯
通過類名也不是不能訪問實例訪問,只是需要我們傳入一個對象。盡管語法支持,但是不建議這樣做。
實例方法與類方法 知識總結
實例方法 : 既可以通過對象調用實例方法,也可以通過類名調用實例方法。只不過通過類名調用實例方法,需要顯示傳遞對象,畫蛇添足,不建議這么做。
類方法 : 既可以通過類名調用類方法,也可以通過對象調用類方法。但是,強烈建議,通過類名調用類方法。
“類方法”與“實例方法”,對“類中屬性”進行訪問
最好,通過實例方法訪問實例屬性,通過類方法訪問類屬性。
class Person:
desc = "人的描述"
def __init__(self, name):
self.name = name
def walk(self):
# 實例方法訪問實例屬性
print(self.name + " is walking")
@classmethod
def c_m(cls):
# 盡管這種方式可以修改類屬性。但是屬於硬編碼(表示代碼寫的太死了),不建議這么做
# Person.desc = "abcd" # 假如以后類名Person修改了,這里還需要修改
# 因為cls就是Person,所以可以用以下方式修改類屬性
cls.desc = "abcd" # 以后就算是:類名Person修改了,這里也不用動。
p = Person("張三")
p1 = Person("李四")
結果如下:
靜態方法
先來看一個例子:
class Person:
@staticmethod
def s_m():
print("這是靜態方法")
# 因為沒有self和cls。既不能訪問類屬性,也不能訪問實例屬性。但是有什么用呢?沒多大作用,其實。不用太關心這個
p = Person()
結果如下:
通過上面的例子,關於靜態方法需要注意以下幾點:
- 注意1 :靜態方法使用@staticmethod 修飾,也與所創建的對象無關;
- 注意2 :沒有self和cls參數。不能訪問類屬性,也不能訪問實例屬性。但是有什么用呢?沒多大作用;
- 注意3 :靜態方法最好通過類名去訪問,雖然對象也可以訪問;