知識點:
- 類屬性與例項屬性;
- 類方法與例項方法;
- 靜態方法;
類屬性與例項屬性
類屬性與例項屬性的區別
-
屬性的繫結不同
- 類屬性與當前類相關(繫結的是當前類),與當前類建立的任何物件無關;
- 例項屬性與當前物件相關(繫結的是當前物件);
-
訪問方式不同
- 對於類屬性,可以通過類名,進行訪問,也可以通過物件進行訪問。但是,通過物件進行訪問,屬於“只讀訪問”,我們不能對其進行修改;
- 對於例項屬性,只能通過建立的物件,進行訪問,不能通過類名進行訪問;
什麼時候定義類屬性?什麼時候定義例項屬性呢?
- ① 定義類屬性
不同物件都一致(完全一樣)的屬性,定義為"類屬性",被大家共享。像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 :靜態方法最好通過類名去訪問,雖然物件也可以訪問;