ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

装饰器: 在不改变原函数的基础上, 动态给函数增加功能

装饰器: 在不改变原函数的基础上, 动态给函数增加功能 面向对象 之 初识 是类之内置的一个装饰器, 的作用在于经由过程特定体式格局, 把一个按正常应当以方法情势调用的执行体, 转化为以属性情势来操控调用。装饰器: 在不改变原函数的基础上, 动态给函数增加功能很多装饰器的些许细节, 之前已然开展过讨论, 其本质是借助变量的引用指针特色以及变量命名空间最终达成的。def out(func): def inner(*args, **kwargs): print(f...{args[0]} is checking...) return func(*args, **kwargs) return inner out def check_2019_nCov(name): msg fokay, {name} is very healthy. return msg ret check_2019_nCov(youge) print(ret) # output ...youge is checking... okay, youge is very health针对这个装饰器, 通常情况下我会更多地将它运用在代码优化方面, 把一个方法进行封装从而使其成为属性, 如此一来在阅读体验上会更优一些。关于具体是怎样实现的, 我也尚未弄明白, 暂且只要能够应用就行。具体的写法是, 在需要用到的那个方法的上面, 使用 进行装饰, 其参数仅仅只有 self, 在调用这个方法的时候, 不需要加上括号。 将方法装饰为属性# 访问类的私有属性 class Foo: def __init__(self, score): self.__score score property # 将方法装饰为属性 def show_score(self): return self.__score if __name__ __main__: s Foo(66) # 在写法上更加优雅, 不用多写 方法() 没用的括号 print(s.show_score) # output: 66就是待在类自身的成员里头玩耍, 在无需传递外部参数的情况之下运用, 表示类的成员属性, 刚开始感觉挺 呢。咱们插句话说一下, 就上例之中, 那个被 所装饰的方法, 它的功能是为外部提供一个能够查看内部属性的接口。其中, 代表私有变量, 它不能被加以直接访问。抱有期望来讲, 然而外部却依旧是能够访问内部变量的, 感觉这算得上是不够严谨的一处地方, 毕竟不存在绝对的安全。s Foo(66) # 外部直接访问私有变量(方法) 是不可以的 print(s.__score) # output AttributeError: Foo object has no attribute __score但是, 经由实例对象 . 类名 _ 的私有属性, 采用这样的途径的话是可行的, 其中缘由是什么呢, 能够直接去探究一下类自身的构造原理。s Foo(66) # 没有绝对的安全哦, 只要互相尊重 print(s._Foo__score) # output 66 相关属性采用上面所提及的那种写法, 给人的感觉好像仅仅只是, 将原本的方法转变成为了属性罢了, 似乎就只是这样, 除去在写法方面相对而言较为简洁优雅一些之外, 那它具体的实际应用场景究竟会是怎样的情况呢?绑定属性-校验-手动实现class Foo: def __init__(self, score): self.score score # 绑定score属性 s Foo(666)更改 score 属性时, 我通常这样写.s.score 666以这样子的, 无比粗暴的方式, 也就是直接把属性给暴露出去的方式, 来进行绑定属性,虽说, 这样子写起来是简单的, 然而, 它没有检验参数, 这就致使其能够被随意修改。运用这般粗野的方式明显是不怎么合乎情理的, 应当针对score开展一回验证, 值、类型等等均可, 也就是当我们去设定score属性之际, 应当要达成两个自定义方法, 一个用来查看值, 另一个用来设置值。class Foo: def get_score(self): 获取属性值 print(self.score) def set_score(self, value): 设置属性值 if not isinstance(value, int): raise ValueError(score 必须为整数哦) if value 100 or value 0: raise ValueError(score 必须在 0-100哦) self.score value if __name__ __main__: f Foo() # 校验通过是可以的 f.set_score(66) f.get_score() # output 66# 随便设置 score 属性就不可以了. if __name__ __main__: f Foo() f.set_score(youge) f.get_score() # output raise ValueError(score 必须为整数哦) ValueError: score 必须为整数哦# 继续 debug if __name__ __main__: f Foo() f.set_score(youge) f.get_score() # output raise ValueError(score 必须在 0-100哦) ValueError: score 必须在 0-100哦case1 绑定属性-校验- 实现class Foo: property # read only def score(self): 获取属性值 return self.score score.setter def score(self, value): 设置属性值 if not isinstance(value, int): raise ValueError(score 必须为整数哦) if value 100 or value 0: raise ValueError(score 必须在 0-100哦) # 这里一定不能 self.socre value 哦, 不然就递归了. self._score value print(fset score {value} successfully.) if __name__ __main__: f Foo() f.score 66 # print(f.score) # output: set score 66 successfullyif __name__ __main__: f Foo() f.score youge # output raise ValueError(score 必须为整数哦) ValueError: score 必须为整数哦case 2 - 封装类属性那再来一个小小的例子, 嗯, 去封装一个名为Book的类, 这个类主要是用来对书籍的名称、价格以及评论进行描述的, 然后, 还要求能够运用装饰器来实现对Book的实例属性的set和get方法进行定义, 也就是要使得实例对象能够以属性的方式去操作方法或者属性。class Book: def __init__(self, name, price, commentNone): self.__name name self.__price price self.__comment comment # 传统方法对price属性进行 设置和访问 def get_price(self): return self.__price def set_price(self, value): self.__price value # price property(get_price, set_price) # property 装饰器对 comment 属性进行 设置和访问 property def my_comment(self): # 默认是 getter, 需要return 或 yeild return self.__comment my_comment.setter def my_comment(self, value): # 检验 if not isinstance(value, float): raise ValueError(must be a decimal number) if value 0 or value 1000: raise ValueError(0 ~ 1000) self.__comment value my_comment.deleter def my_comment(self): print(delete this atrr...)小结
返回列表