python之裝飾器初識

1、@abstractmethod

一、抽象類的做用:規範編程模式
多人開發、複雜的需求、後期的擴展
是一種用來幫助咱們完成規範化的手段編程

二、如何定義抽象類
1,from abc import ABCMeta,abstractmethod
2,在這個類建立的時候指定 metaclass = ABCMeta
3,在你但願子類要實現的方法的上一行加上一個 @abstractmethod裝飾器

三、使用抽象類
1,繼承這個類
2,必須實現這個類中被@abstractmethod裝飾器裝飾的方法微信

四、實例ide

# 支付功能

from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):  # 模板的功能
    @abstractmethod                               # abstractmethod是一個裝飾器,裝飾器怎麼用?放在函數或者類的上一行
    def pay(self): pass

# 這樣就構建了一個抽象類Payment,並聲明瞭子類必需要實現的方法是 pay(),若子類沒有定義pay(),則實例化時會報錯


class Alipay(Payment):  # 繼承了抽象類,就必須實現抽象類中被@abstractmethod裝飾器裝飾的方法 pay()
    def pay(self, money):
        print('使用支付寶支付了%s元' % money)


class Wechatpay(Payment):
    def pay(self, money):
        print('使用微信支付了%s元' % money)


class My_pay(Payment):  # 這裏沒有定義pay()方法,那麼在實例化的時候機會報錯
    def fuqian(self,money):
        print('你支付了%s元' % money)


def pay(obj, money):
    obj.pay(money)


# p = Payment()  # 報錯 抽象類不能被實例化

a = Alipay()
# a.pay(100)
pay(a,100)  # 使用支付寶支付了100元

we = Wechatpay()
# we.pay(200)
pay(we,200)  # 使用微信支付了200元

my = My_pay()  # 報錯:類中沒有定義抽象類的pay方法
pay(my,300)
View Code

2、@property  setter deleter

一、
裝飾器的分類:
裝飾函數
裝飾方法 : property
裝飾類函數

裝飾器函數都怎麼用:
在函數、方法、類的上面一行直接@裝飾器的名字post

二、property是一個裝飾器函數(就是用來解決剛纔私有屬性的問題)
property:將一個方法假裝成一個屬性微信支付

2-1學生信息中,姓名不想給別人修改,就設置爲私有屬性,在定義一個同名的方法假裝成屬性,便於查找ui

class Student:
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):    # 聲明瞭@property使用此方法的時候就能夠不寫括號,就假裝成了屬性
        return self.__name

xiaoming = Student('小明',18)
print(xiaoming.name)  # 小明

xiaoming.name = '小狗'  # 改:報錯
print(xiaoming.name)
View Code

 

2-2圓的半徑能夠修改,可是面積和周長應該是屬性的形式比較正確,可是直接設置爲屬性,圓的半徑改了後,
周長和麪積並不會改變this

class Circle:
    def __init__(self,r):
        self.r = r
        self.area = 3.14 * self.r ** 2
        self.perimeter = 2 * 3.14 * self.r
c = Circle(6)
print(c.area)  # 113.04
print(c.perimeter)  # 37.68

c.r = 3  # 改變了半徑
print(c.area)  # 113.04
print(c.perimeter)  # 37.68
View Code

 

2-3所以上面的圓能夠寫成這樣:spa

class Circle:
    def __init__(self,r):
        self.r = r

    @property
    def area(self):
        return 3.14 * self.r ** 2

    @property
    def perimeter(self):
        return 2 * 3.14 * self.r

c = Circle(6)
print(c.area)  # 113.04
print(c.perimeter)  # 37.68

c.r = 3  # 改變了半徑
print(c.area)  # 28.26
print(c.perimeter)  # 18.84
View Code

 

2-4完整的property

一、定義
一個方法被假裝成屬性以後,應該能夠執行一個屬性的增刪改查操做,
增長和修改就對應着被setter裝飾的方法,
刪除一個屬性對應着被deleter裝飾的方法。code

@property:把方法假裝成屬性

@被property裝飾的方法名.setter:
當被property裝飾的方法,又實現了一個同名方法,且被setter裝飾器裝飾了,
那麼在對被裝飾的方法賦值的時候,就會觸發被setter裝飾器裝飾的方法,
這個方法必需要傳一個參數接收等號後面的值,
是用來保護一個變量在修改的時候可以添加一些保護條件。

@被property裝飾的方法名.deleter:
當被property裝飾的方法,又實現了一個同名方法,且被deleter裝飾器裝飾了,
那麼在對被裝飾的方法進行刪除的操做時,就會觸發被deleter裝飾器裝飾的方法,
這個方法並不能在執行的時候真的刪除這個屬性,而是你在代碼中執行什麼就有什麼效果.

二、例題

複製代碼
學生類
class Student:
    def __init__(self,name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self,new):
        if type(new) is str:   #由於名字是字符串類型的,咱們這樣設置能夠保證只能用字符串修更名字
            self.__name = new

    @name.deleter
    def name(self):
        del self.__name

xiaoming = Student('小明')
print(xiaoming.name)   #小明

xiaoming.name = 123   # 不是字符串修改不了
print(xiaoming.name)   # 小明

xiaoming.name = '小花貓'
print(xiaoming.name)   # 小花貓

del xiaoming.name
print(xiaoming.__dict__) # {} 空字典


水果類:
class Fruits:
    __discount = 0.7

    def __init__(self,price):
        self.__price = price

    @property
    def price(self):
        return self.__price * Fruits.__discount

    @price.setter
    def price(self,new):
        if type(new) is int or float:
            self.__price = new

    @price.deleter
    def price(self):
        del self.__price

banana = Fruits(10)
print(banana.price)  # 折扣價7.0


banana.price = 9
print(banana.price) # 折扣價6.3

del banana.price
print(banana.__dict__)  # {} 空字典
複製代碼

三、總結

被setter和deleter裝飾的方法名必須和被property裝飾的方法名一致,對象.方法名 不加括號 能夠調用被property裝飾的方法,
當對被property裝飾的方法賦值時,就會觸發被setter裝飾的方法,當對被property裝飾的方法進行刪除del操做時,就會觸發
被deleter裝飾的方法。
注意:(通常來講用的最多的是property,其餘兩個看狀況而使用)

 

3、@classmethod

類方法:
用@classmethod裝飾
類方法默認形參用cls表示,而不用self
能夠直接經過類去修改類的屬性,不須要實例化

複製代碼
class Fruits:
    __discount = 0.7  # 類的靜態屬性

    def __init__(self,price):
        self.__price = price  # 對象的私有屬性

    @property
    def price(self):
        return self.__price * Fruits.__discount

    @classmethod
    def change_discount(cls,new):  # 類方法默認形參用cls表示,而不用self
        cls.__discount = new


Fruits.change_discount(0.6)
print(Fruits.__dict__)  # '_Fruits__discount': 0.6


類方法的特色:
只使用類中的資源,且這個資源能夠直接用類名引用,那這個方法應該被改成一個類方法
複製代碼

 

4、@staticmethod

靜態方法
被@staticmethod裝飾的方法,不使用類中的命名空間也不使用對象的命名空間,
能夠傳參,也能夠不傳參,沒有默認參數(self,cls),至關於一個類外的普通的方法,
不一樣的是調用的時候須要 類名.方法名

複製代碼
class Student:
    @staticmethod
    def login():
        print('登陸成功')

Student.login())
複製代碼
相關文章
相關標籤/搜索