Python基礎(二十):面向對象“類”第三課——類成員


知識點:

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

類屬性與實例屬性

類屬性與實例屬性的區別

  • 屬性的綁定不同

    • 類屬性與當前類相關(綁定的是當前類),與當前類創建的任何對象無關;
    • 實例屬性與當前對象相關(綁定的是當前對象);
  • 訪問方式不同

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

什么時候定義類屬性?什么時候定義實例屬性呢?

  • ① 定義類屬性

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM