1.靜態方法:在類方法前增長關鍵字@staticmethod,將普通方法變成靜態方法,不能再次傳值,不能訪問實例變量或者類變量,與類的關係僅僅是經過類名進行調用python
2.類方法:在類方法前增長關鍵字@classmethod,類方法只能訪問類變量,不能訪問實例變量函數
3.屬性方法:(重點)在類方法前增長關鍵字@property,調用的時候經過屬性同樣的方式訪問(去掉括號調用),能夠經過類私有屬性加@setter從新賦值,@deleter刪除私有屬性後方能刪除屬性方法ui
class Dog(object): def __init__(self,name): self.name=name def eat(self,food): print('%s is eating %s'%(self.name,food)) obj1=Dog('hashiqi') obj1.eat('baozi')
正常輸出:hashiqi is eating baozispa
增長關鍵字staticmethod:code
class Dog(object): def __init__(self,name): self.name=name @staticmethod def eat(self,food): print('%s is eating %s'%(self.name,food)) obj1=Dog('hashiqi') obj1.eat('baozi')
報錯:對象
Traceback (most recent call last): File "D:/001python/01course/day07/static_method.py", line 11, in <module> obj1.eat('baozi') TypeError: eat() missing 1 required positional argument: 'food'
eat的實參沒有傳給selfblog
結論:增長關鍵字@staticmethod後,類的方法變成了單純的函數,沒法訪問類或者實例中的任何屬性,僅增長類名進行調用接口
若是非要給靜態方法傳類屬性,能夠直接將對象傳進去---沒有意義:ip
class Dog(object): def __init__(self,name): self.name=name @staticmethod def eat(self): print('%s is eating '%(self.name)) obj1=Dog('hashiqi') obj1.eat(obj1)
輸出:hashiqi is eating 內存
類方法沒法訪問實例屬性
class Dog(object): #name='yzw' def __init__(self,name): self.name=name @classmethod def eat(self): print('%s is eating '%(self.name)) obj1=Dog('hashiqi') obj1.eat()
報錯以下:
print('%s is eating '%(self.name)) AttributeError: type object 'Dog' has no attribute 'name'
類方法只能訪問類屬性:
class Dog(object): name='yzw' def __init__(self,name): self.name=name @classmethod def eat(self): print('%s is eating '%(self.name)) obj1=Dog('hashiqi') obj1.eat()
輸入:yzw is eating
沒法正常使用調用方法
class Dog(object): def __init__(self,name): self.name=name @property def eat(self): print('%s is eating '%(self.name)) obj1=Dog('hashiqi') obj1.eat()
報錯以下:
obj1.eat() TypeError: 'NoneType' object is not callable
改爲調用屬性的方法,也就是把括號去掉:
class Dog(object): def __init__(self,name): self.name=name @property def eat(self): print('%s is eating '%(self.name)) obj1=Dog('hashiqi') obj1.eat
正常輸出:hashiqi is eating
結論:把一個方法變成一個靜態屬性,沒法經過()進行調用,它能夠經過"對象.屬性"進行調用
屬性普通賦值也會報錯:
class Dog(object): def __init__(self,name): self.name=name @property def eat(self): print('%s is eating '%(self.name)) obj1=Dog('hashiqi') obj1.eat obj1.eat='value' error: obj1.eat='value' AttributeError: can't set attribute
結論:屬性方法能夠經過屬性調用方式獲取,可是不能直接給予賦值
經過特殊處理給屬性方法傳值:
再寫一個同名的方法,使用@xxx.setter關鍵字進行賦值,可是怎麼才能給屬性裏面的形參傳值呢?
class Dog(object): def __init__(self,name): self.name=name @property def eat(self): print('%s is eating '%(self.name)) @eat.setter def eat(self,food): print(food) obj1=Dog('hashiqi') #正常實例化對象 obj1.eat # 調用屬性方法 obj1.eat='value' #調用屬性賦值方法 hashiqi is eating value
屬性傳值二:
經過在構造方法裏增長私有屬性,給屬性方法其餘形參傳值
class Dog(object): def __init__(self,name): self.name=name self.__food=None @property def eat(self): print('%s is eating'%self.name,self.__food) @eat.setter def eat(self,food): print(food) self.__food=food d=Dog('hashiqi') # 1.正常實例化對象 d.eat # 2.正常調用屬性方法 輸出:hashiqi is eating None,此時self.__food的值取構造方法的初始值 d.eat='包子' # 3.經過setter屬性賦值方法給方法賦值 d.eat # 4.再次調用屬性方法,輸出屬性方法的結果,此時屬性方法調用setter裏設置的值 hashiqi is eating None baozi hashiqi is eating baozi
刪除屬性方法--沒法刪除:
class Dog(object): def __init__(self,name): self.name=name self.__food=None @property def eat(self): print('%s is eating %s '%(self.name,self.__food)) @eat.setter def eat(self,food): print(food) self.__food=food obj1=Dog('hashiqi') obj1.eat obj1.eat='baozi' obj1.eat del obj1.eat error AttributeError: can't delete attribute
刪除屬性方法--先刪除私有屬性
class Dog(object): def __init__(self,name): self.name=name self.__food=None @property def eat(self): print('%s is eating %s '%(self.name,self.__food)) @eat.setter def eat(self,food): print(food) self.__food=food @eat.deleter def eat(self): del self.__food print('had been deleted') obj1=Dog('hashiqi') obj1.eat obj1.eat='baozi' obj1.eat del obj1.eat hashiqi is eating None baozi hashiqi is eating baozi had been deleted
刪除再進行調用報錯:
class Dog(object): def __init__(self,name): self.name=name self.__food=None @property def eat(self): print('%s is eating %s '%(self.name,self.__food)) @eat.setter def eat(self,food): print(food) self.__food=food @eat.deleter def eat(self): del self.__food print('had been deleted') obj1=Dog('hashiqi') obj1.eat obj1.eat='baozi' obj1.eat del obj1.eat obj1.eat # 依然是去調用靜態方法,此時私有屬性已被刪除 error print('%s is eating %s '%(self.name,self.__food)) AttributeError: 'Dog' object has no attribute '_Dog__food'
屬性方法用途:隱藏細節,暴露簡單接口給用戶
案例:查詢航空班次狀態
1.調用航空公司API查詢
2.對查詢結果進行分析
3.將分析後的結果返回頁面,用戶不關心過程/方法,只關心狀態,也就是屬性方法的結果
class Flight(object): def __init__(self,name): self.fly_name=name def checking_status(self): print('checking flight %s status...'%self.fly_name) return 3 @property def Flight_status(self): status=self.checking_status() if status == 0: print('flight had got canceled') if status == 1: print('flight is arrived') if status == 2: print('flight has departured already...') if status == 3: print('cannot confirm the flight status ... check later pls') @Flight_status.setter def Flight_status(self,status): status_dict={0:'canceled',1:'arrived',2:"departured"} print('status has changed to %s'%status_dict.get(status)) fly1=Flight('A380') fly1.Flight_status fly1.Flight_status = 1 output: checking flight A380 status... cannot confirm the flight status ... check later pls status has changed to arrived
1.__doc__ 打印類下面的註釋信息
class Class_name(object): '''class description''' pass print(Class_name.__doc__) output:class description
2.__module__ 打印模塊的名字 __class__ 打印類的名字
from fly import Flight t=Flight('A380') print(t.__module__) print(t.__class__) output: status has changed to arrived fly <class 'fly.Flight'>
3.__init__ 構造方法,實例化類的時候自動建立
4.__del__ 析構方法,通常不定義,系統會自動執行回收垃圾
5.__call__ 對象後面加括號,觸發執行
class Dog(object): def __init__(self): pass def __call__(self, *args, **kwargs): print(*args,**kwargs) d1=Dog() d1(1,2,3) output: 1 2 3
6.__dict__ 打印字典形式的類屬性方法或者實例屬性
class Dog(object): address='earth' def __init__(self,name,age): self.name=name self.age=age def func1(self, *args, **kwargs): print(*args,**kwargs) print(Dog.__dict__) #以字典形式打印類的全部屬性和方法 d1=Dog('hashiqi',19) print(d1.__dict__) #以字典形式打印實例的屬性
7.__str__ 若是一個勒種定義了__str__方法,那麼打印對象的時候,默認輸出該方法的返回值
class Dog(object): address='earth' def __init__(self,name,age): self.name=name self.age=age def func1(self, *args, **kwargs): print(*args,**kwargs) def __str__(self): # 若是沒有定義str方法,將打印對象的內存地址 return ('return value') d1=Dog('hashiqi',19) print(d1) output:return value
8. item字典方法,使用起來像操縱字典,實際上是類內置方法
class Dog(object): def __getitem__(self, item): print('getitem',item) def __setitem__(self, key, value): print('setitem',key,value) def __delitem__(self, key): print('delitem',key) d1=Dog() # 1.實例化對象 value1=d1['key1'] # 2.調用getitem方法 d1['key2']='value2' # 3.調用setitem方法 del d1['key3'] # 4.調用delitem方法 output: getitem key1 setitem key2 value2 delitem key3
class Dog(object): def __init__(self,name): self.name=name def eat(self): print('%s is eating...'%self.name) d1=Dog('hashiqi') choice =input('input>>').strip() #判斷有沒有方法 print(hasattr(d1,choice)) #判斷輸入的字符串在內存地址中是否存在 print(getattr(d1,choice)) #獲取內存地址,加括號直接調用 getattr(d1,choice)()
通常這麼用:
class Dog(object): def __init__(self,name): self.name=name def eat(self,food): print('%s is eating %s'%(self.name,food)) d1=Dog('hashiqi') choice =input('input>>').strip() #輸入一個方法,若是方法在類中存在,則未true if hasattr(d1,choice): func=getattr(d1,choice) #增長一個變量,有助於傳入參數 func('baozi') #將參數傳給判斷成功的方法 output: input>>eat hashiqi is eating baozi
動態裝進取一個新方法:
class Dog(object): def __init__(self,name): self.name=name def eat(self,food): print('%s is eating %s'%(self.name,food)) def bulk(self): print("%s is yelling"%self.name) d1=Dog('hashiqi') choice =input('input>>').strip() #輸入一個方法,若是方法在類中存在,則未true if hasattr(d1,choice): func=getattr(d1,choice) #增長一個變量,有助於傳入參數 func('baozi') #將參數傳給判斷成功的方法 else: setattr(d1,choice,bulk) d1.talk(d1) #至關於調用類裏面的talk方法,talk實際上就是類外面的bulk函數 output: input>>talk hashiqi is yelling
動態裝進去一個屬性
class Dog(object): def __init__(self,name): self.name=name def eat(self,food): print('%s is eating %s'%(self.name,food)) def bulk(self): print("%s is yelling"%self.name) d1=Dog('hashiqi') choice =input('input>>').strip() #輸入一個方法,若是方法在類中存在,則未true if hasattr(d1,choice): func=getattr(d1,choice) #增長一個變量,有助於傳入參數 func('baozi') #將參數傳給判斷成功的方法,若是輸入一個已經存在的屬性,則不能加括號調用 else: # setattr(d1,choice,bulk) # d1.talk(d1) #至關於調用類裏面的talk方法,talk實際上就是類外面的bulk函數 setattr(d1,choice,2) print(getattr(d1,choice)) output: input>>asdf 2
刪除一個屬性
class Dog(object): def __init__(self,name): self.name=name def eat(self,food): print('%s is eating %s'%(self.name,food)) def bulk(self): print("%s is yelling"%self.name) d1=Dog('hashiqi') choice =input('input>>').strip() #輸入一個方法,若是方法在類中存在,則未true if hasattr(d1,choice): delattr(d1,choice) else: # setattr(d1,choice,bulk) # d1.talk(d1) #至關於調用類裏面的talk方法,talk實際上就是類外面的bulk函數 setattr(d1,choice,2) print(getattr(d1,choice)) print(d1.name)
output:
print(d1.name)
AttributeError: 'Dog' object has no attribute 'name'
再變化
class Dog(object): def __init__(self,name): self.name=name def eat(self,food): print('%s is eating %s'%(self.name,food)) def bulk(self): print("%s is yelling"%self.name) d1=Dog('hashiqi') choice =input('input>>').strip() #輸入一個方法,若是方法在類中存在,則未true if hasattr(d1,choice): getattr(d1,choice) else: setattr(d1,choice,bulk) func = getattr(d1,choice) # 這裏無論choice輸入任何東西,都只調用bulk 就是把字符串choice反射成內存中bulk的地址 func(d1)
try: 可能出錯的語句 except 錯誤關鍵字1 as 別名: 別名捕獲了錯誤的詳細信息 處理語句 except 錯誤關鍵子2 as 別名: 處理語句 或者 except (錯誤關鍵字1,錯誤關鍵字2,。。。) as 別名: 多個錯誤沒法定位 except Exception: 無論什麼錯誤都放到這裏,不建議一開始用 else: 若是except都沒有捕捉到異常 就在這裏處理 finally: 無論有沒有出現錯誤,都會執行
自定義異常
class CustomException(Exception): def __init__(self,msg): self.msg=msg try: raise CustomException('error') #這裏實例化一個類了 except CustomException as e: # e保存的就是msg的值 print(e) output: error