1、類的定義和語法

class dog(object): #用class定義類 "dog class" #對類的說明 def __init__(self,name): #構造函數或者是構造方法,也可以叫初始化方法 self.name = name def sayhi(self): #類方法 "sayhi funcation" #對類方法的說明 print("hello,i am a dog,my name is ",self.name) d = dog("AAAA") #定義一個d的對象,叫實例 d.sayhi() #調用實例的方法
2、self關鍵字
self 這個關鍵字相當於實例化對象本身(self相當於d),在實例化過程中,把自己傳進去了
3、函數__init__() 、__del__()
在類中__init__()函數叫構造函數,又叫構造方法,也可以叫初始化函數。它的作用就是初始化實例時,初始化傳入實例的的默認值。如果不寫__init__(),就會調用的默認為空的__init__(),說白了,這個方法不管你寫不寫,都會調用,而且,一旦實例化就會調用。

class dog(object): "dog class" def __init__(self,name): #構造方法,不寫調用默認的構造方法 self.name = name def eat(self,food): print("the dog name is {0},it like food is {1}".format(self.name,food)) d = dog("AAAA") d.eat("hotdog") #輸出結果 the dog name is alex,it like food is hotdog
在類中__del__()函數叫做析構函數,是在實例銷毀的時候調用的函數

class dog(object): "dog class" def __init__(self,name): self.name = name def sayhi(self): print("the dog {0} is sayhi".format(self.name)) def __del__(self): #定義析構函數 print("del.....run...") d = dog("alex") del d import time time.sleep(5) #輸出 del.....run...
①析構函數說明時候調用呢?
其實每一個對象都是一個應用,就像每一個房間都有門牌號一樣, 只要這個對象的引用被清空時,就會自動執行,就像上面的del d,其實python中有自動垃圾回收機制,會定時去的去回收一些被清空的應用,而析構函數就是在引用被清空之后會自動執行
②析構函數的作用?
比如說server端接受很多客戶端的連接,當你手動屏蔽你的sever端的時候,這個時候客戶端還在正常的連接,如果sever端用類寫的,你就可以delete server端的同時,在__del__()寫一些東西,說去close掉很多客戶端的連接。說白了,析構函數就是做一些程序的收尾工作。
4、類的實例化過程圖解:
小結:
- 其實self,就是實例本身!你實例化時python會自動把這個實例本身通過self參數傳進去。
- 定義類(class dog(object))-> 實例化(d = dog()) -> 實例化對象(d)
- __init__()構造函數
- self.name = name 被稱為屬性、成員變量、字段
- def sayhi(self) 被稱為方法、動態屬性
5、訪問類屬性

class dog(object): "dog class" def __init__(self, name): self.name = name # 類的成員變量 def sayhi(self): print("the dog {0} is sayhi".format(self.name)) def eat(self, food): # 傳入一個參數,參數名:food print("the dog name is {0},it like food is {1}".format(self.name, food)) d = dog("AAAA") # 實例化對象 d.sayhi() # 調sayhi方法 d.eat("hotdog") # 調eat方法 # 輸出結果 the dog AAAA is sayhi the dog name is AAAA,it like food is hotdog
①為什么eat方法里面會傳入一個food的參數名呢?而這個為什么不能再其他方法里面用呢?而self.name就可以呢?
因為food它只是作為eat方法的一個參數,不是類的成員變量,只能在自己的方法里面使用,而self.name是類的成員變量,它是類的屬性,所以可以被調用。
②為什么類的每一個方法第一個參數都是self呢?
是因為類在實例化的時候,需要把實例對象本身傳進來,好去調用對象本身的屬性和方法
6、修改類屬性

class dog(object): "dog class" def __init__(self,name,age): self.name = name self.age = age def sayhi(self,update_age): #傳入一個update_age參數 self.age = update_age #修改對象的age屬性 d = dog("AAAA",18) d.sayhi(22) #第1次在類的方法中修改 print(d.age) d.age = 19 #第2次在類外面修改 print(d.age) #輸出 22 19
注:就是說在類的方法中或者類的外面都可以修改類的屬性
7、私有屬性
定義私有屬性

class dog(object): "dog class" def __init__(self, name, age): self.name = name self.age = age self.__sex = "man" # 定義私有屬性__sex def sayhi(self, update_age): self.age = update_age d = dog("AAAA", 18) print(d.__sex) # 訪問私有屬性__sex # 輸出 Traceback (most recent call last): print(d.__sex) # 訪問私有屬性__sex AttributeError: 'dog' object has no attribute '__sex' # 報錯,說沒有__sex這個屬性
上面的例子可以看出,私有屬性是不可以訪問的,更不可以修改。但是我們就想訪問,但是不去修改,我們怎么辦呢?
get方法訪問私有屬性

class dog(object): "dog class" def __init__(self, name): self.name = name self.__sex = "man" # 定義私有屬性sex def get_sex(self): # 定義get方法 return self.__sex # 返回私有屬性sex值 d = dog("AAAA") d_sex = d.get_sex() # 調用實例對象d的get_sex()方法獲取私有屬性sex print(d_sex) # 輸出結果 man
注:這種方法只能訪問私有屬性,但是不能更改私有屬性
強制訪問私有屬性

class dog(object): "dog class" def __init__(self,name): self.name = name self.__sex = "man" #定義私有方法sex d = dog("AAAA") print(d._dog__sex) #訪問私有屬性sex d._dog__sex = "woman" #修改私有屬性sex print(d._dog__sex) #打印修改后的值 #輸出結果 man woman
注:這種方法就更為暴力,可以訪問也可以修改,就是:對象名._類名__屬性名
8、公有屬性
定義公有屬性:在類中直接定義的,可以提供這個類所屬的所有對象都可以訪問的屬性

class dog(object): "dog class" nationality = "JP" # 定義公有屬性nationality def __init__(self, name): self.name = name d1 = dog("AAAA") d2 = dog("sanjiang") print(d1.nationality, d2.nationality) # 所有的成員變量都可以訪問 # 輸出結果 JP JP
d1.name,d2.name也可以訪問,也可以修改, 為什么不能叫公有屬性呢?

class dog(object): "dog class" nationality = "JP" def __init__(self, name): self.name = name d1 = dog("AAAA") d2 = dog("sanjiang") print(d1.name, d2.name) # 輸出結果 AAAA sanjiang
注:上面的name是每個對象的屬性,並不是共享,而是獨立的 ,所以不能叫做公有屬性
訪問/修改公有屬性

class dog(object): "dog class" nationality = "JP" # 定義公有屬性 def __init__(self, name): self.name = name d1 = dog("AAAA") d2 = dog("sanjiang") print(dog.nationality) # 訪問公有屬性 dog.nationality = "US" # 修改公有屬性 print(dog.nationality) # 輸出 JP US
注 :公有屬性不僅可以通過所屬類的所有對象訪問,還可以通過類本身直接訪問和修改
公有屬性特性
公有屬性不是私有屬性,它提供所有對象訪問和修改,那我們其中有一個對象正在修改公共屬性發生什么變化呢?

class dog(object): "dog class" nationality = "JP" def __init__(self, name): self.name = name d1 = dog("AAAA") d2 = dog("sanjiang") print("firsthand change...") print(d1.nationality, d2.nationality) print("brfore change ...") d1.nationality = "CN" # 對象的d1修改公共屬性得值 print(d1.nationality, d2.nationality) print("after change ....") dog.nationality = "US" # dog類本省修改公共屬性的值 print(d1.nationality, d2.nationality) #輸出結果 firsthand change... JP JP brfore change ... CN JP #d1對象的公共屬性被修改了 after change .... US US #d1對象的公共屬性值沒有隨着類本身的公共屬性值修改而修改
解疑:
- 對象d1去訪問nationality屬性時,如果在成員屬性中找不到,就會找公共屬性,也就是說自己的屬性找不到就去找父親的屬性
- d1.nationality="CN" 相當於在自己對象內部又重新創建了一個新的局部變量,這個局部變量已經脫離了class本身,跟這個類已經沒有半毛錢關系了,只是名字一樣而已,如果不改,還是找全局的。