python3.x 基礎七:面向對象進階

類的高級方法:

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 內存

  • 類方法  --關鍵字@classmethod

類方法沒法訪問實例屬性

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 

  • 屬性方法--關鍵字@property

沒法正常使用調用方法

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

類的本質

反射

  • hasattr(obj,name_str) 判斷一個對象裏是否有對應的字符串方法
  • getattr(obj,name_str)根據字符串去獲取obj對象裏對應的方法的內存地址
  • setattr(obj,'y',z) 至關於與obj.y=z
  • delattr
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
相關文章
相關標籤/搜索