面向對象編程 object oriented programming(OOP)(第二篇)

函數裝飾器

對於某個函數,如果我們希望在不改變該函數代碼的前提下,爲該函數增加額外的功能,那麼就可以使用裝飾器來裝飾該函數。
裝飾器是一個函數,裝飾器接收一個函數作爲參數(傳入的實參是被裝飾的函數)
裝飾器的內部嵌套定義另一個函數,內函數中會引用裝飾器的參數,並且裝飾器的返回值是內函數。
爲了讓內函數接收任意類型的參數,將內函數的形參定義爲(*args,**kwargs)
在函數中,首先完成爲被裝飾函數添加的新功能,然後調用被裝飾的函數。
把裝飾器應用到被裝飾函數的語法爲:在被裝飾函數的前面添加“@裝飾器的函數名”
def notice(func):
    def wrapper(*args,**kwargs):
        print("公告:注意身體!")
        return func(*args,**kwargs)
    return wrapper
@notice
def add(a,b):
    return a + b
@notice
def subt(a,b):
    return a - b   
print(add(3,5))
>公告:注意身體!
 8
print(subt(8,3))
>公告:注意身體!
 5

類方法

類方法指的是類對象中使用裝飾器@classmethod進行裝飾的方法
在類對象中定義類方法時,必須使用裝飾器@classmethod進行裝飾,此外,第一個形參表示類對象,其對應的實參由系統自動傳入。第一個形參的名稱通常是cls。
類對象可以被類對象所調用,語法格式爲:類對象.方法名([實參])或:cls.方法名([實參])。
類對象也可以實例對象所調用,語法格式爲:實例對象.方法名([實參])或:self.方法名([實參])。
class MyClass(object):
#在類對象中定義類方法
    @classmethod
    def class_func(cls,a,b):
        print(a,b)
#通過類對象調用類方法
MyClass.class_func('hi','hello!')
>hi hello!
#通過實例對象調用類方法
mc = MyClass
mc.class_func(1,2)
>1 2
PS:可以用實例對象調用類方法,但是不能用類對象調用實例方法

靜態方法

類對象的靜態方法只是一個普通函數,把某個普通函數歸屬於類對象,可能只是爲了易於代碼管理。在類對象中定義靜態方法時,必須使用裝飾器@staticmethod進行裝飾
靜態方法 只是一個普通函數,因此,第一個形參沒有特殊含義和要求。
靜態方法可以被類對象所調用,語法格式爲:類對象.方法名([實參])或:cls.方法名([實參])。
靜態方法也可以實例對象所調用,語法格式爲:實例對象.方法名([實參])或:self.方法名([實參])。
調用靜態方法時的參數傳遞與調用普通函數是一樣的。
class MyClass(object):
    @staticmethod
    def sm(p1,p2):
        print(p1,p2)
MyClass.sm(1,2)
>1 2
mc = MyClass()
mc.sm(1,2)
>1 2

訪問控制

訪問控制指的是:控制類對象的屬性和方法在類對象的外部是否可以直接訪問。
如果在類對象的某個屬性或方法前添加兩個下劃線__,那麼在類對象的外部就不能直接訪問該屬性或方法了。
class MyClass(object):
    def __init__(self):
        self.__pia = 18
    def __pim(self):
        print("__pim()被調用了")
mc = MyClass()
print(mc.__pia)
>#報錯
>---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-229fd1431afb> in <module>()
      5         print("__pim()被調用了")
      6 mc = MyClass()
----> 7 print(mc.__pia)

AttributeError: 'MyClass' object has no attribute '__pia'

mc.__pia()
>#報錯
>---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-a65b2ec13347> in <module>()
----> 1 mc.__pia()

AttributeError: 'MyClass' object has no attribute '__pia'

print(mc._MyClass__pia)
>18
mc._MyClass__pim()
>__pim()被調用了
仍然可以在類對象的外部動態綁定名爲__xxx的屬性或方法,這與類對象內部名爲__xxx的屬性或方法是不同的。
mc.__pia = "hi"
print(mc.__pia)
>hi
print(dir(mc))
>['_MyClass__pia', '_MyClass__pim', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__pia', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'do_sth']
除了在類對象的屬性或方法前添加兩個下劃線__,還可以在類對象的屬性或方式前添加單下劃線_,這表示:雖然可以在類對象的外部訪問該屬性或方法,但是最好不要訪問。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章