Python中類的定義與使用
一、類的簡述
類時面向物件程式設計的核心內容。通常把具有相同特徵(資料元素)與行為(功能)的事物描述定義為一個類,類是一個抽象的概念,把類例項化既可以得到一個物件。
因此,物件的抽象是類,類的具體化就是物件,也可以說類的例項是物件,類實際上就是一種資料型別。
類具有屬性,它是物件的狀態的抽象,用資料結構來描述類的屬性。類具有操作,它是物件的行為的抽象,用操作名和實現該操作的方法來描述。
物件具有狀態,一個物件用資料值來描述它的狀態。物件還有操作,用於改變物件的狀態,物件及其操作就是物件的行為。
比如:把人類即為一個抽象的類,“老王”則為一個的人即物件。每個物件都有一些相同的特徵,但具體的數值卻不一定相同。如:每個人都有“姓名”,“國籍”,“年齡”等特徵。還具有一些相同的行為,如:“吃飯”,“睡覺”,“工作”等
可以簡潔的描述為:Person ({"name", "country", "age"}, {"eat", "sleep", "work"})。
在這裡可以看到,類有兩種屬性:資料屬性,行為屬性。在類中行為屬性一般稱為“方法”。
二、資料屬性
屬性有兩種,類屬性,例項屬性(物件的屬性),通常把所有物件共同擁有的屬性定義為類屬性,如:每個人都只有兩隻眼等,例項屬性則時根據不同的物件賦值不一樣的值,如:姓名等
下面來看一個簡單的程式碼實現:
class Person(object):
eyes = 2
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print("%s 吃:%s" % (self.name, food))
def eye(self):
print("%s" % (self.eyes))
p1 = Person("張三", 18)
p2 = Person("李四", 19)
print("類的屬性:", Person.__dict__)
print("物件p1的屬性:", p1.__dict__)
print("物件p2的屬性:", p2.__dict__)
p1.eat("番茄炒雞蛋")
p1.eye()
#輸出結果
類的屬性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000002059BABB6A8>, 'eat': <function Person.eat at 0x000002059BABB730>, 'eye': <function Person.eye at 0x000002059BABBAE8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
物件p1的屬性: {'name': '張三', 'age': 18}
物件p2的屬性: {'name': '李四', 'age': 19}
張三 吃:番茄炒雞蛋
2
先輸出,類, p1, p2 的屬性,得出結論(1)例項化的物件只具備自己的資料屬性(2)類的屬性包含:類的資料屬性、函式屬性。
這裡要注意幾點:
1)方法的第一個引數不用傳值,但必須在定義,因為python直譯器,做了這樣的一件事,自動把呼叫的物件當作第一個引數傳值給方法,通常定義為self
2)物件訪問屬性的過程,查詢屬性__dict__字典,找到就訪問這個屬性,當物件的屬性字典不存在該屬性時,則會去類屬性裡邊找,類裡邊也不存在時則會報錯
3)類屬性所有通過該類建立的物件都可以訪問
1、類屬性的增刪該查
class Person(object):
# 類屬性新增的第一種方式
eyes = 2
def __init__(self, name):
self.name = name
def say(self, w):
print("%s說了%s" % (self.name, w))
print("1--類的屬性:", Person.__dict__)
# 類屬性新增的第二種方式
Person.arm = 2
print("2--新增類的屬性:", Person.__dict__)
# 類屬性修改
Person.arm = 1
print("3--修改類的屬性:", Person.__dict__)
# 類屬性刪除
del Person.eyes
print("4--刪除類的屬性:", Person.__dict__
#輸出結果
1--類的屬性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
2--新增類的屬性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'arm': 2}
3--修改類的屬性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'arm': 1}
4--刪除類的屬性: {'__module__': '__main__', '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'arm': 1}
看程式碼應該就差不多明白類屬性的操作了。
注:類屬性一般一經定義,不會在執行的過程中增加、刪除類的屬性
定義類屬性一般只用第一種方法,其它的騷操作了解就好,忘了它吧
2、例項屬性的增刪改查
class Person(object):
def __init__(self, name):
# 例項屬性新增第一種方式
self.name = name
def say(self, w):
print("%s說了%s" % (self.name, w))
p1 = Person("張三")
p2 = Person("李四")
print("1--p1的屬性:", p1.__dict__)
print("1--p2的屬性:", p2.__dict__)
# 例項屬性新增第二種方式
p1.age = 20
print("2--p1的屬性:", p1.__dict__)
print("2--p2的屬性:", p2.__dict__)
# 刪除例項屬性
del p1.name
print("3--p1的屬性:", p1.__dict__)
print("3--p2的屬性:", p2.__dict__)
# 修改例項屬性
p1.age = 10
print("4--p1的屬性:", p1.__dict__)
print("4--p2的屬性:", p2.__dict__)
# 輸出結果
1--p1的屬性: {'name': '張三'}
1--p2的屬性: {'name': '李四'}
2--p1的屬性: {'name': '張三', 'age': 20}
2--p2的屬性: {'name': '李四'}
3--p1的屬性: {'age': 20}
3--p2的屬性: {'name': '李四'}
4--p1的屬性: {'age': 10}
4--p2的屬性: {'name': '李四'}
例項屬性跟類屬性的操作差不多。從上也可以得出結論,對物件 p1 的操作並不影響 p2 的屬性。
注:例項屬性一般放在init方法裡邊初始化,不會在執行的過程中增加、刪除物件的屬性
三、方法
1、普通的方法
上邊沒有@符號修飾,供外部例項呼叫,普通的方法也叫例項方法,但雖然叫例項方法但卻與類相關,儲存在類的屬性中
2、類方法
上邊有@classmethod修飾,定義時第一個引數必須為"cls",並通過cls來呼叫類屬性,無法訪問例項屬性
3、靜態方法()
上邊有@staticmethod,與類相關但不需要訪問屬性,無法呼叫其它方法與屬性
class Person(object):
eyes = 2
def __init__(self, name):
self.name = name
def say(self, w): # 普通方法
print("%s say %s" % (self.name, w))
@classmethod
def cls_md(cls): # 類方法
print("這是類方法", cls.eyes)
@staticmethod
def stat(): # 靜態方法
print("這是靜態方法")
p1 = Person("zhangs")
print(Person.__dict__)
p1.say("hello")
p1.cls_md()
p1.stat()
# 輸出結果
{'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001DF5205B6A8>, 'say': <function Person.say at 0x000001DF5205B730>, 'cls_md': <classmethod object at 0x000001DF5205ABE0>, 'stat': <staticmethod object at 0x000001DF5205AEB8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
zhangs say hello
這是類方法 2
這是靜態方法
4、方法的增(瞭解即可)
class Person(object):
eyes = 2
def __init__(self, name):
self.name = name
def say2(self): # 普通方法
print("%s 增加普通方法" % (self.name))
@classmethod
def ha2(cls): # 類方法
print("增加類方法", cls.eyes)
@staticmethod
def stat2(): # 靜態方法
print("增加靜態方法")
print("增加前:", Person.__dict__)
Person.say2 = say2
Person.ha2 = ha2
Person.stat2 = stat2
print("增加後:", Person.__dict__)
p1 = Person("zhangs")
p1.say2()
p1.ha2()
p1.stat2()
# 輸出結果
增加前: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001468207B6A8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
增加後: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001468207B6A8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'say2': <function say2 at 0x0000014681ECC1E0>, 'ha2': <classmethod object at 0x000001468207A390>, 'stat2': <staticmethod object at 0x000001468207AB70>}
zhangs 增加普通方法
增加類方法 2
增加靜態方法
四、私有化
1、xx:公有變數
2、_xx:單前置下劃線,私有化屬性或方法,類物件和子類可以訪問,from module import * 禁止匯入,但from module import _xx 或 Import module還可以匯入
3、__xx:雙前置下劃線,私有屬性或方法,外部無法訪問到(因為名字重整了,__xx變為_classname__xx),兼具_xx的特性
4、__xx__:前後雙下劃線,使用者名稱空間的魔法物件或屬性,例如:__init__,一般不要自己定義這樣的變數名
5、xx_:單後置下劃線,與python關鍵字重名+_區分,不要定義這樣的變數名
Linux公社的RSS地址:ofollow,noindex" target="_blank">https://www.linuxidc.com/rssFeed.aspx
本文永久更新連結地址:https://www.linuxidc.com/Linux/2018-09/154281.htm