# 類的裝飾器 # 對不同的類使用裝飾器加上不同的類屬性 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}