广州番禺Python, Java小班周末班培训
薯条老师在广州做Python和Java的小班培训,一个班最多10人,学员的平均就业薪资有11K。不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习。培训的课程有Python爬虫,Python后端开发,Python办公自动化,Python大数据分析,Python量化投资,Python机器学习,Java中高级后端开发。授课详情请点击:https://www.chipscoco.com/?cate=6
16.9.1 类装饰器
类装饰器的核心在于通过__init__方法和__call__方法来实现装饰器逻辑。 在14.5节中介绍了函数装饰器,类装饰器与函数装饰器的区别在于:函数装饰器将代码的扩展逻辑转移到函数中,而类装饰器将扩展逻辑转移到装饰器类中。类装饰器的语法结构:
Python
"""
(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:
Python
# __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:Python
# __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即为对应的属性名。
代码实例:
Python
# __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())
# 输出为lisa
Python的设计目标是简单和优雅,为让客户端对属性进行更简单地操作,Python提供了属性装饰器:propery。使用property对成员方法进行装饰时,等同于实现了get_xx方法,该成员方法的函数名通常与属性名保持一致:Python
# __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)
# 输出为kitty
Python同时提供了setter装饰器,用setter装饰器来装饰成员方法时,等同于实现了set_xx方法。使用setter进行装饰时,需要加上方法名的前缀, 在语义上表示该方法用来对属性进行设置:Python
# __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学习资料: