類的裝飾器


# 類的裝飾器
# 對不同的類使用裝飾器加上不同的類屬性
def typed(**kwargs):
    def deco(obj):
        for k, v in kwargs.items():
            setattr(obj, k, v)
        return obj

    return deco


@typed(x=1, y=2, z=3)  # 1、typed(x=1, y=2, z=3)->deco  2、@deco->Foo=deco(Foo)
class Foo:
    pass


print(Foo.__dict__)


@typed(name='alex')
class Bar:
    pass

print(Bar.__dict__)


# 通過類的裝飾器再對描述符檢測數據類型的例子進行改寫

class Typed:  # 定義描述符的類,必須是一個數據描述符
    def __init__(self, key, expected_type):  # 定義一個實例化方法,主要用於傳實例字典的key,和期望的數據類型
        self.key = key
        self.expected_type = expected_type

    def __get__(self, instance, owner):
        # instance 代表實例(p1) owener代表實例的擁有者(People)
        return instance.__dict__[self.key]  # 返回實例字典key的值

    def __set__(self, instance, value):
        # instance 代表實例(p1) value代表傳入的值
        if not isinstance(value, self.expected_type):  # 判斷用戶傳入的name如果不是字符串
            print('你傳入的類型不是%s' % self.expected_type)
            return  # return終止此方法,不執行下面的賦值
        instance.__dict__[self.key] = value


def classtyped(**kwargs):  # kwargs={'name':'str', 'age':'int', 'salary':'float'}
    def deco(obj):  # obj=People
        for k, v in kwargs.items():  # (('name', str), ('age', int), ('salary', float))
            setattr(obj, k, Typed(k, v))  # setattr(People, 'name', Typed('name', str))
        return obj

    return deco


@classtyped(name=str, age=int, salary=float)
class People:

    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.salary = salary


p1 = People('alex', 18, 2584.25)
print(p1.__dict__)  # {'name': 'alex', 'age': 18, 'salary': 2584.25}
p1.name = 'egon'
print(p1.__dict__)  # {'name': 'egon', 'age': 18, 'salary': 2584.25}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM