5. 再次接触装饰器,增加一种数据结构代替 if_else 的写法
在 Python 中,可以使用装饰器创建复合函数,复合函数是包含多个源函数功能的单函数。
概念比较抽象,简单的说明就是装饰器可以给某个函数增加功能,并且不用改变原函数代码,在滚雪球学 Python 第二轮中,我们已经学习了装饰器的基本使用,参考博客:https://dream.blog.csdn.net/article/details/114413806
typing
前 4 篇文章下来,让橡皮擦觉得有必要先普及一下 typing
注解模块相关知识。
该模块是 Python3.5 之后新增加的功能,可以校验数据类型,但是在 Python 运行时并不强制执行函数和变量类型注解,也就是不强制验证,如果需要验证,需要借助于第三方工具。
大家可以作为知识储备先学习起来。
类型别名
可以将 Python 原来存在的数据类型,重新定义为新的类型别名,例如下述代码:
从 typing
模块导入了 List
,表示序列的每一项必须是同一类型,如果不一致,则直接返回 list
或 List[Any]
或注明可能的类型,比如:List[Union[str, int]]
。
常用的类型如下:
Dict
:格式为Dict[str, int]
其中key
、value
必须的类型必须填写,尽量保证value
类型一致,如果不一致,则直接返回dic
或Dict[str, Any]
或注明可能的类型,比如:Dict[str, Union[str, int]]
;Set
:格式为Set[int]
,变量必须是同一类型,如果不一致,则直接返回set
或Set[Any]
或 注明可能的类型,比如:Set[Union[str, int]]
;List
:上述已经说明;Tuple
:格式为Tuple[int, str]
,如果有多个同类型返回值,可写为Tuple[str, ...]
;FrozenSet
:冻结的集合,冻结后集合不能再添加或删除任何元素。
其余需要单独说明的内容:
NewType
用 NewType
可以新创建类型,例如创建一个 Ca
:
当然这种类型,只有静态检查器会强制执行这些检查。
Any
Any
是一种特殊的类型。静态类型检查器将所有类型视为与 Any
兼容,反之亦然, Any
也与所有类型相兼容。
Callable
回调函数可以使用 Callable[[Arg1Type, Arg2Type],ReturnType]
的类型注释,如果只指定回调函数的返回值类型,则可以使用 Callable[..., ReturnType]
的形式,例如下述代码:
该代码表示 FuncType
是一个回调函数,参数不限制,返回值为任意类型。
OptionalOptional[X]
等价于 Union[X, None]
,所以它是可选类型。
TypeVar 类型变量,主要是为静态类型检查器提供支持,用于泛型类型与泛型函数定义的参数。TypeVar
约束一个类型集合,但不允许单个约束。
除此之外,还可以使用类型绑定,确保数据类型,例如下述代码:
typing
模块还有很多其它知识点,后续逐步补充,接下来咱们在原有知识的基础上,学习点难的。
装饰器
下面要定义的是,一个处理空 None 值的装饰器,代码与应用如下所示。
代码中实现了一个空值判断的装饰器,被其装饰的函数可以忽略 None 值。
特别注意:装饰器只返回函数而不处理其中的数据
条件表达式
本篇博客原计划全部写成装饰器相关知识点,后来发现有的地方理解起来难度有点过大,所以切换为条件表达式在函数式编程中的应用。
在 Python 中可以使用一些数据结构,去模拟 if 语句的效果,而且效果会很好,在开始学习前,先看一下下述代码:
上述代码演示的是当字典中,出现相同键时,会用第二个值替换第一个值。
基于上述逻辑,你可以实现一个 max
函数。
上述代码先计算 a>=b
或者 a<=b
然后获取字典中的 True
键对应的值,最后返回的是 f()
(因为 f
的值是匿名函数)
如果 a==b
返回那个值都可以。
基于此,我们可以实现一个阶乘函数。
运行一下上述代码,理解一下这样的写法吧,这种写法就修改了传统的 if...else
结构,通过一种数据结构进行了代替。
最后再补充一遍装饰器基本用法
在 Python 中用装饰器可以修改函数,或者类的可调用对象(类的实例)。
被装饰器修饰的函数,在调用的时候,优先调用装饰器函数,然后在装饰器函数的内部去调用原函数。
学好装饰器的第一步是学好函数。
函数三两句那些事儿
函数是头等对象,可以赋值给其它变量
函数可以作为其它函数的输入参数
函数可以嵌套在其它函数内部
被嵌套的函数可以访问父函数的作用域,一般把这个技术点叫做闭包,但需要注意的是,这种访问是只读的,嵌套的函数不能给外部变量赋值,如果违反会出现如下错误:
函数可以作为返回值
函数装饰器
装饰器主要的实现,都是由 wrapper
函数实现的,展示一个装饰器的案例:
上述代码就是装饰器,可以看到就是主函数作为参数传递给了装饰器,在 Python 中对该内容存在一个语法糖 @
,可以直接替换 decorator_demo(func)
。
上述代码虽然使用原函数名 func
调用函数,但是函数在运行的时候确被装饰器劫持了,修改了函数的执行过程。
类中的装饰器
首先定义一个类,一个简单的类:
get_name
方法必须由类的对象,即 b
去调用,无法直接通过 Boy
类名调用,下面通过装饰器 @staticmethod
,创建一个静态方法,该方法可以直接被调用,静态方法没有 self
参数,可以应用于实例与类本身。
类中除了静态方法以外,还有类方法,它使用的装饰器是 @classmethod
。
类方法的参数为 cls
,使用之后,可以判断出类名,包括其子类。所有的内容都集成在下述代码,可以敲打一遍进行学习。
写在后面
以上内容就是本文的全部内容。
更多精彩
版权声明: 本文为 InfoQ 作者【梦想橡皮擦】的原创文章。
原文链接:【http://xie.infoq.cn/article/81f4887b13a5c1495b44569b4】。文章转载请联系作者。
评论