effective python 第二版_Effective python(二):函数

1,遇到特殊情况抛出异常而不是返回None

2,有些情况需要将重要的消息优先显示在其它内容前面,例如在用户界面绘制的时候,实现方法如下

defsort_priority(values,group):defhelper(x):if x in group: #如果在优先组内,那就排到最前面

return (0,x) #python会以特殊的形式比较两个元组,解释看下面

return (1,x)

values.sort(key=helper)

Python比较元组(或列表):可以想象比较的过程[(0,7),(0,8),(1,3)],那么Python进行比较的时候,会先进行元组的一个元素排序,然后再根据排序结果,对元组中第二个元素基于第一个元素的位置进行排序,当然最后输出的结果还是正常的列表[7,8,3],这只是其中比较的过程

3,nonlocal声明获取闭包内的数据,但它不能延伸至模块级别,而且复杂的函数情况下应该尽量少用,如果越写越复杂,可以将相关状态封装成辅助类

classSorter(object):def __init__(self,group):

self.group=group

self.found=Falsedef __call__(self,x): #修改这个后能够使得将类的实例当函数一样调用

if x inself.group:

self.found=Truereturn(0,x)return (1,x)

4,对于返回列表的函数,可以使用yield改写return,同时要注意,返回的是一个迭代器,若有需要可以使用list()进行转换。若数据量非常大,不建议使用list转换而占用内存,若需要使用部分数据,可以使用list(islice(iter,start,end))进行对迭代器的切片操作。

5,处理迭代器参数注意事项

处理迭代器参数的时候应该注意,迭代器只能产生一轮结果,对其进行两次遍历操作是没有效果的,而且不会报错

迭代器是有状态的,应该避免多次对其操作

处理如上问题有两个解决方法:(1) 对迭代器进行一次复制转换为列表,(2) 参数设置为一个产生迭代的函数,(3) 编写一种新的实现迭代器的协议的容器类

在执行for x in y这样的语句时,python实际上会调用iter(y),内置的iter函数又会调用y.__iter__这个方法,该方法必须返回迭代器对象,而迭代器本身,又实现了特殊的__next__方法,for会反复的调用迭代器内置的next函数,直到耗尽产生StopIteration异常

实现新容器类只需要在__iter__方法中使用yeild即可

这种迭代器容器类使用方法和使用迭代器函数一样,实例化的容器类就可以当迭代器使用

为了防止传入的参数变成迭代器而不是容器的实例对象,可以使用语句判断是否是迭代器而报错if iter(arg) is iter(arg): #当传给iter函数的是迭代器时,会返回它本身,当传给iter函数是容器实例对象时,会返回一个新的迭代器

代码如下

6,可变长参数

对*arg参数传参时要记得对迭代器使用*解包

可变长参数传给函数时,总是会先转化成元组,这就意味着python会先把该生成器完整的迭代一轮,所以只使用于数据量较小的情况,否则可能会导致内存耗尽

7,关键字参数

位置参数必须出现在关键字参数前(不管是在调用时候,还是命名时)

所有位置参数都可以用关键字参数形式传递

使用关键字参数的好处是,可以与原有代码兼容,这样,添加新参数的时候就不需要去修改原有的调用传参,或者迁移大量参数

可选参数,也可以通过位置传参指定,但尽量不用

8,动态默认值参数

def log(message,when=datetime.now()): #这种形式并不会在每次函数调用时多次定义默认值,而是会在函数定义时只执行一次创建默认值

若想实现动态的默认值,习惯上是先写成None,然后用文档字符串把参数的行为描述处理,在函数内写when=datetime.now()

def decode(data,default={}) 这样定义也有BUG,所有使用默认形式调用decode的代码都将共享一份字典,解决方法是将其定义为None,在文档字符串中描述其行为

9,定义只能以关键字形式指定参数

def func(n,d,*,i=False,c=False)  # 其中的*号,代表位置参数就此终结,后面的不能用位置传参的形式指定,只能用关键字形式指定

如果同时使用*args和**kwargs时,必须*args参数列要在**kwargs前

takes 0 positional arguments but 1 was given注意出现这类错误要记得解包**,*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值