Python基礎(二十):物件導向“類”第三課——類成員

pure3417發表於2021-04-13

知識點:

  • 類屬性與例項屬性;
  • 類方法與例項方法;
  • 靜態方法;

類屬性與例項屬性

類屬性與例項屬性的區別

  • 屬性的繫結不同

    • 類屬性與當前類相關(繫結的是當前類),與當前類建立的任何物件無關;
    • 例項屬性與當前物件相關(繫結的是當前物件);
  • 訪問方式不同

    • 對於類屬性,可以通過類名,進行訪問,也可以通過物件進行訪問。但是,通過物件進行訪問,屬於“只讀訪問”,我們不能對其進行修改;
    • 對於例項屬性,只能通過建立的物件,進行訪問,不能通過類名進行訪問;

什麼時候定義類屬性?什麼時候定義例項屬性呢?

  • ① 定義類屬性

不同物件都一致(完全一樣)的屬性,定義為"類屬性",被大家共享。像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 :靜態方法最好通過類名去訪問,雖然物件也可以訪問;

相關文章