effective python学习笔记_函数

函数返回值尽量不要超过三个

局限性:当返回参数过多时,有时会搞混哪个是哪个,可能返回的两个值反了

解决方法:如果参数过多,可以组装*变量返回,或者自定义轻量类型或namedtuple返回

有意外情况时尽量抛异常而不是返回None

例子:当if判断除法运算结果时,即使结果为0运算成功,if也会判断为False

解决方法:1用二元组表示函数返回结果,第一个元素是运算是否成功,第二个元素是运算结果;

在闭包里使用外围作用域变量

py函数作用域可分为4个,从小到大依次是函数作用域,函数外围作用域(最内层函数以外,最外层函数以内,最内层函数也叫闭包),全局作用域,内置作用域(len str内置函数所在作用域)

若想给闭包外的外围作用域里的变量赋值,需要使用nonlocal,这样赋值时变量就先从外围作用域找变量。如果不用nonlocal则赋值会被当成在最内层作用域(闭包)内的新变量定义,而不会将值赋给外围作用域的同名变量

尽量少用nonlocal,因为可能会有潜在副作用,且较难看出问题所在

和nonlocal互补的一个是global,作用是声明当前变量作用域为全局作用域

用数量可变的位置参数给函数清晰的参数列表

位置参数形如*args,写法类似于解包

缺点1:传参时,函数会将多于的参数组成一个元组传给函数的位置参数,而组元组需要遍历元素。当元素数量过多时还会占用内存和时间

缺点2:当需要更新函数参数时,函数内对参数调用逻辑存在耦合,需要大量同步修改,且入参时如果参数数量变化,会导致位置参数前面的默认参数类别因为位置变化而类型变化,引起潜在bug。为解决此种问题,可以考虑添加参数类型为关键字参数

优点:接受可变个数的参数

适用性:适用于参数数量不是很多,可以提高可读性

关键字参数表示可选行为

函数可同时使用位置参数和关键字参数,当定义参数和入参时,位置参数需要在关键字参数前面,否则报错

调用函数时,关键字参数的key不可以重复,否则报错

优点:1可读性号,易懂 2可以在函数定义时设置默认值 3关键字参数支持灵活添加新参数,有向后兼容作用

用None和docstring描述默认值会变的参数

背景:比如log写日志需要日志时间戳,如果没传入时间则设为当前时间,但如果将datetime.datetime.now()赋值为默认参数,这个表达式只会在定义时计算结果,是个固定值,不会每次调用都是当前时间

解决方法:对于需要变化的函数默认值,用None替代,然后docstring写清楚怎么处理,在函数逻辑里处理此种情况

设置参数只能通过位置参数传递或关键字参数传递

函数定义时,当只定义了位置参数和关键字参数,调用函数传参时,其实一个参数既可以以位置参数传入也可以以关键字参数传入,如果需要固定一些参数传入形式,比如只能以位置参数形式传入,不能以关键字参数传入,可在定义函数时使用*。这样做了以后,如果以错误传参形式传参就会报错

怎么做:函数定义时,可以通过*实现*左边的参数都只能通过位置参数传入而*右边的参数都只能通过关键字参数传入,例如def test(a, b, *, c='c', d='d')

这样实际上位置参数也可以接受关键字参数方式传入,因为*只保证*右边的参数强制以关键字参数传入否则报错,但无法保证*左边的以位置参数传入,py3.8及以后版本实现了对位置参数类似的支持,即/号。/左边的参数强制以位置参数传入,否则报错。当/ 和 *同时出现在函数参数定义中,/和*中间的参数可以位置参数和关键字参数形式传入

用functools.wraps定义函数修饰器

会导致什么问题:之前提过,用装饰器修饰函数后,函数的__name__会变成装饰器内层的函数名,还会在pickle.dumps时报错,报错无法找到原始函数的位置,不光如此,函数还有一些其他内置属性,被装饰时候会被装饰函数取代

解决方案:使用functools.wraps装饰装饰器里的内层函数,会保留函数大部分原始的属性不被替换

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值