广州番禺Python, Java小班周末班培训
薯条老师在广州做Python和Java的小班培训,一个班最多10人,学员的平均就业薪资有11K。不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习。培训的课程有Python爬虫,Python后端开发,Python办公自动化,Python大数据分析,Python量化投资,Python机器学习,Java中高级后端开发。授课详情请点击:http://chipscoco.com/?cate=6
16.9.1 类装饰器
类装饰器的核心在于通过__init__方法和__call__方法来实现装饰器逻辑。 在14.5节中介绍了函数装饰器,类装饰器与函数装饰器的区别在于:函数装饰器将代码的扩展逻辑转移到函数中,而类装饰器将扩展逻辑转移到装饰器类中。类装饰器的语法结构:
""" (1) 同函数装饰器一样,类装饰器也分为带参数和不带参数的结构 (2) 不带参数的类装饰器,通过__init__方法传递被装饰的函数,并在__call__方法中定义扩展逻辑 """ # 不带参数的类装饰器语法结构 class ClassName: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): # 在__call__方法内部定义扩展逻辑 return self.func(*args, **kwargs) """ (3) 带参数的类装饰器,通过__init__方法来定义装饰器的参数,在__call__方法中 传递被装饰的函数 """ # 带参数的类装饰器语法结构 class ClassName: # 在__init__方法中定义类装饰器的参数 def __init__(self, *args, **kwargs): pass # 在__call__方法中传递被装饰的函数 def __call__(self, func): # 需要再定义一个闭包函数,传递函数的参数 def __closure(*args, **kwargs): func(*args, **kwargs) return __closure
现在通过类装饰的语法结构,来定义一个简单的验证器类Validator,用来验证函数的参数类型是否合法。
不带参数的Validator:
# __desc__ = 定义一个不带参数的类装饰器Validator class Validator: def __init__(self, func): self.__func = func # __types表示合法的参数类型 self.__types = (float, int) def __call__(self, *args): for _ in args: if not isinstance(_, self.__types): # 如果参数类型非法,直接返回0 return 0 # 参数合法,返回被装饰的函数的返回值 return self.__func(*args) # 使用Validator进行装饰 @Validator def accumulate(*numbers): sum_of_numbers = 0 for _ in numbers: sum_of_numbers += _ return sum_of_numbers print(accumulate(1,2,3,4)) # 函数的输出为10 # 传递一个非法的参数类型,比如字符串类型 print(accumulate(1,2,"3",4)) # 由于参数列表中包含非法的参数类型,所以函数的输出为0带参数的Validator:
# __desc__ = 定义一个带参数的类装饰器Validator class Validator: # 在__init__方法中定义类装饰器的参数 def __init__(self, types): # __types表示合法的参数类型 self.__types = types # 在__call__方法中传递被装饰的函数 def __call__(self, func): def __verify(*args): for _ in args: if not isinstance(_, self.__types): # 如果参数类型不合法,则直接返回0 return 0 return func(*args) # 返回该闭包函数 return __verify # 使用带参数的Validator进行装饰,参数类型必须是int,bool的其中一种 @Validator((int,bool)) def accumulate(*numbers): sum_of_numbers = 0 for _ in numbers: sum_of_numbers += _ return sum_of_numbers print(accumulate(1,2,3,4)) # 函数的输出为10 # 传递一个非法的参数类型,比如浮点类型 print(accumulate(1,2,3.0,4)) # 函数的输出为0
16.9.2 属性装饰器
如果在属性名前面加上双下划线的前缀,那么属性就变成了“私有”属性。私有属性只在类/对象作用域中可见,客户端如需访问私有属性,需要借助该类型的公有方法。在C++等编程语言中,通常定义get_xx方法来读取私有属性,定义set_xx方法来对私有属性进行修改,这里的xx即为对应的属性名。
代码实例:
# __desc__ = 定义get_xx和set_xx方法对私有属性进行读写操作 class Cat: def __init__(self,name): self.__name = name # 定义get_name方法来读取__name的值 def get_name(self): return self.__name # 定义set_name方法来修改__name的值 def set_name(self, new_name): self.__name = new_name kitty = Cat("kitty") # 执行get_name方法来读取私有属性__name print(kitty.get_name()) # 执行set_name方法来为私有属性__name赋值 print(kitty.set_name("lisa")) print(kitty.get_name()) # 输出为lisaPython的设计目标是简单和优雅,为让客户端对属性进行更简单地操作,Python提供了属性装饰器:propery。使用property对成员方法进行装饰时,等同于实现了get_xx方法,该成员方法的函数名通常与属性名保持一致:
# __desc__ = 使用property进行装饰 class Cat: def __init__(self,name): self.__name = name # 使用property对name方法进行装饰 @property def name(self): return self.__name kitty = Cat("kitty") # 可以像访问成员属性一样来调用name方法 print(kitty.name) # 输出为kittyPython同时提供了setter装饰器,用setter装饰器来装饰成员方法时,等同于实现了set_xx方法。使用setter进行装饰时,需要加上方法名的前缀, 在语义上表示该方法用来对属性进行设置:
# __desc__ = 使用property.setter进行装饰 class Cat: def __init__(self,name): self.__name = name # 使用property对name方法进行装饰 @property def name(self): return self.__name # 使用name.setter进行装饰,表示该name方法用来对属性进行设置 @name.setter def name(self, new_name): self.__name = new_name kitty = Cat("kitty") # 可以像直接赋值成员属性一样来调用name方法 kitty.name = "lisa" print(kitty.name) # 输出为lisa
16.9.3 最具实力的小班培训
薯条老师在广州做Python和Java的小班培训,一个班最多10人。不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习。打算参加小班培训的同学,必须遵守薯条老师的学习安排,认真做作业和项目。把知识学好,学扎实,那么找到一份高薪的工作就是很简单的一件事。
(1) Python后端工程师高薪就业班,月薪11K-18K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,免费领取课程大纲
(3) Java后端开发工程师高薪就业班,月薪11K-20K, 免费领取课程大纲
(4) Python大数据分析,量化投资就业班,月薪12K-25K,免费领取课程大纲
扫码免费领取Python学习资料: