類和實(shí)例
python是一個(gè)面向?qū)ο蟮恼Z言,而面向?qū)ο笞钪匾母拍罹褪穷惡蛯?shí)例, 記得剛學(xué)習(xí)的時(shí)候不太理解這些概念,直到老師說了一句”物以類聚”. 沒錯(cuò)就是類, 歸類
物以類聚
類其實(shí)就是把一些相同特性的事物歸成一類, 比如人
1
2
|
class Person( object ): pass |
我們定義了人這個(gè)類, 但人有一些特性,比如 兩個(gè)眼睛,一個(gè)嘴巴, 我們把這些添加進(jìn)去
1
2
3
|
class Person( object ): eyes = 2 mouth = 1 |
已經(jīng)把人的一些信息寫進(jìn)去了,但是人還有名字, 比如我mink. 好吧我不能虧待自己我得把這些添加進(jìn)去
1
2
3
4
|
class Person( object ): eyes = 2 mouth = 1 name = mink |
太完美了,一個(gè)人終于完成了. 上帝用了一天我就用了一分鐘(開個(gè)玩笑), 我們讀一下信息. 人類他有兩個(gè)眼睛,一個(gè)嘴巴,還有名字叫mink. - -! 有點(diǎn)不對(duì),mink是我的名字啊~ 怎么人類叫mink呢
mink是人類的名字, 人類的名字是mink顯然是錯(cuò)誤的, “wo” 應(yīng)該是人類的個(gè)體,是個(gè)單個(gè)例子
1
2
3
4
5
6
7
8
|
class Person( object ): eyes = 2 mouth = 1 def __init__( self , name): self .name = name me = Person( 'mink' ) |
現(xiàn)在我終于有了自己的名字而不是給大家共用, 這個(gè)方法叫實(shí)例但是我有一個(gè)別人不會(huì)的技能, 我不受重力影響.
1
2
3
4
5
6
7
8
9
10
11
12
|
class Person( object ): eyes = 2 mouth = 1 def __init__( self , name) self .name = name def jineng( self , txt): print "%s %s" % ( self .name, txt) me = Person( 'mink' ) me.jineng( "我不受重力影響, 我會(huì)飛" ) |
類方法和靜態(tài)方法
python中可以經(jīng)常看到@classmethod和@staticmethod, 被稱為類方法和實(shí)例方法.
1
2
3
4
5
6
|
class Animal( object ): name = 'lili' age = 1 cat = Animal() print cat.name, cat.age # print 'lili' 1 |
創(chuàng)建了一個(gè)動(dòng)物類, 生成了一個(gè)cat的實(shí)例, 打印cat的名字和年齡, 可以看出返回的是Animal這個(gè)類的屬性, 也就是實(shí)例訪問了類的屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 顯示內(nèi)容是一樣的 print cat.name, cat.age print Animal.name, Animal.age 給Animal類添加一個(gè)方法(函數(shù)) class Animal( object ): name = 'lili' age = 1 def edit( self , name, age): self .name = name self .age = age cat = Animal() cat.edit( 'rol' , 2 ) print cat.name, cat.age # print 'rol' 2 print Animal.name, Animal.age # print 'lili' 1 |
也就是說這個(gè)默認(rèn)添加的方法是一個(gè)實(shí)例的方法, 實(shí)例方法修改了實(shí)例的屬性,而類的屬性不改變
1
2
3
4
5
6
7
8
9
10
|
# 我們修改一下這個(gè)函數(shù) def edit( self , name, age): name = name self .age = age cat = Animal() cat.edit( 'rol' , 2 ) print cat.name, cat.age # pirnt 'rol' 2 print Animal.name, cat.age # print 'lili' 1 |
說明實(shí)例方法不能修改類的屬性, 但我想修改類的屬性怎么辦
1
2
3
4
5
6
7
8
9
10
11
|
# 再一次修改edit @classmethod def edit( cls , name, age): cls .name = name cls .age = age cat = Animal() cat.edit( 'rol' , 2 ) print cat.name, cat.age # print 'rol' 2 print Animal.name, Animal.age # print 'rol' 2 |
這里需要注意的是edit函數(shù)的第一個(gè)參數(shù)有self變?yōu)閏ls, python中建議大家在類的方法中使用cls而實(shí)例方法的參數(shù)為self, 而且這里說明了實(shí)例可以使用類的方法(函數(shù))
那么我在給這個(gè)類添加init方法來初始化屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class Animal( object ): name = 'lili' age = 1 def __init__( self , name, age): self .name = name self .age = age ... cat = Animal( 'kuku' , 4 ) cat.edit( 'rol' , 2 ) print cat.name, cat.age # print 'kuku' 4 print Animal.name, Animal.age # print 'rol' 2 |
添加__init__以后, cat不再使用類的屬性,而修改了edit方法也沒有改變cat實(shí)例的屬性.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 添加staticmethod @staticmethod def say_name(name = None ): if not name: name = self .name print 'my name is %s.' % name cat = Animal( 'kaka' , 3 ) cat.say_name() # 運(yùn)行的話會(huì)報(bào) NameError: global name 'self' is not defined # 那是不是沒給他添加self字段, 所以沒找到 def say_name( self , name = None ): ... cat.say_name() # TypeError: say_name() takes at least 1 argument(0 given), 顯示缺少參數(shù) |
這說明staticmethod 不能使用實(shí)例的屬性和方法, 當(dāng)然也使用不了類. 那么反過來呢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 我們修改一下代碼 # 先創(chuàng)建一個(gè)實(shí)例的方法, 他使用類的staticmethod @staticmethod def say_name(name): print 'my name is %s.' % name def say( self ): self .say_name( self .name) @classmethod def _say( cls ): cls .say_name( cls .name) cat = Animal( 'kaka' , 3 ) cat.say() cat._say() |
可以通過類方法和實(shí)例方法訪問staticmethod.
總結(jié)一下:
靜態(tài)方法(staticmethod)
- 靜態(tài)方法不能使用實(shí)例的屬性和方法
- 靜態(tài)方法不能使用類的屬性和方法
- 靜態(tài)方法可以通過類或?qū)嵗{(diào)用
- 靜態(tài)方法等于作用域在類中的全局函數(shù)
類方法(classmethod)
- 類方法可以使用類的屬性和方法
- 類的方法可以使用靜態(tài)方法
- 類的方法可以通過類或?qū)嵗{(diào)用