连载|想用Python做自动化测试?Python函数入门
“ 函数是 Python 程序中不可或缺的一部分,它是的程序模块化、清晰化。Python的很多功能都是通过内置函数提供的,比如 sorted() 表示对一个集合序列排序,len() 表示返回一个集合序列的长度大小等等。这节课,我们主要来学习 Python 的自定义函数。”
10.1 定义函数
使用def关键字
函数可以有返回值也可以没有返回值
# content of test_sample.pydef inc(x): # 有返回值return x + 1def test_answer(): # 没有返回值assert inc(3) == 5
10.2 调用函数
add_one=inc(3)
函数被调用时,这个函数此前必须定义过
10.3 函数的参数
10.3.1 位置参数
def divmod(x, y): # known case of builtins.divmod""" Return the tuple (x//y, x%y). Invariant: div*y + mod == x. """return (0, 0)
这是一个Python内置的获得商和余数的函数。这个函数有两个参数:x和y,这两个参数都是位置参数,调用这个函数时,要按照顺序传入的两个实参值,实参值会依次赋给参数x和y。
10.3.2 默认值参数
def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):pass
这是Python内置的打开文件的函数,调用open打开文件时,可以只传递file文件路径,其他的参数可以不传递实参值,因为其他的参数都具有默认值。mode是打开文件的模式,默认值是r,表示以读的方式打开文件,默认值参数必须指向不可变对象。
不要这样:
def add_end(li=[]):pass
要这样:
def add_end(li=None):pass
10.3.3 变长参数
可以给函数一次性传递多个参数,或者传递一个列表或元组。定义函数时在参数名前加一个星号*。
def calc(*numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum
函数calc的功能是求任意多个参数的平方和。函数定义时,在参数名加一个星号*。这样的函数,在调用时,可以传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。实际例子如下:
calc(1, 2,3,4)calc(1, 2)calc()nums = [1, 2, 3]calc(*nums) # 还可以传递列表或者元组等进去
max是python内置的求最大值的函数。它的定义如下:
def max(*args, key=None): # known special case of max"""max(iterable, *[, default=obj, key=func]) -> valuemax(arg1, arg2, *args, *[, key=func]) -> valueWith a single iterable argument, return its biggest item. Thedefault keyword-only argument specifies an object to return ifthe provided iterable is empty.With two or more arguments, return the largest argument."""pass
第一个参数是一个变长参数,上面举了两个例子,第一个参数可以是可迭代对象,也可以是多个参数。返回值是多个参数中的最大值,或者可迭代对象中的最大值。比如:
print(max(1, 2, 3, 4, -9, -5)) # 多个参数print(max([1, 2, 3, 4, -9, -5])) # 可迭代对象,这里是一个列表
max函数还有一个默认值参数key,接受一个函数名,这时max函数返回的值是,将args参数分别用到key函数后的结果中的最大值。比如,找出一个数字列表中绝对值最大的元素:
max([1, 2, 3, 4, -9, -5], key=abs)
10.3.4 关键字参数
下面这个sorted函数是Python内置的排序函数,它的第一参数是一个变长参数,第二个参数是个关键字参数,关键字参数是以两个星号开头。
def sorted(*args, **kwargs): # real signature unknown"""Return a new list containing all items from the iterable in ascending order.A custom key function can be supplied to customize the sort order, and thereverse flag can be set to request the result in descending order."""pass
sorted函数默认是升序排序的,可以传入一个关键字参数reverse进行降序排序。方式是:
print(sorted([1, 2, 3, 4, -9, -5], reverse=True))
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个字典。
再来自定义一个:
def person(name, age, **kwargs):print(name,age,kwargs)
关键字参数可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。传递关键字参数有两种方式:
传入字典
extra = {'city': 'Beijing', 'job': 'Engineer'}person('Jack', 24, **extra) # 字典参数名签名放两个**
直接传入key=value
person('Jack', 24, salary=10000, department='finace')
10.3.5 参数组合
定义函数时,参数顺序必须是:位置参数、默认参数、变长参数、关键字参数。定义顺序不能乱。
def f1(a, b, c=0, *args, **kw):pass
10.4 看懂Python源码中函数的定义
有些朋友平时反映,看不懂官方文档中介绍函数的说明,比如查看min的源码:
def min(*args, key=None): # known special case of min"""min(iterable, *[, default=obj, key=func]) -> valuemin(arg1, arg2, *args, *[, key=func]) -> valueWith a single iterable argument, return its smallest item. Thedefault keyword-only argument specifies an object to return ifthe provided iterable is empty.With two or more arguments, return the smallest argument."""pass
min 函数的源码文档中,举了两个例子,其中的形参有 * 符号,又有 []?他们都表示啥意思呢?
函数形参列表中符号 * 表示,后面的形参只能为关键字参数,不能为位置参数,[]里面的参数是可选的,不是必填的,例如传递一个key参数和default参数时,必须写明参数名:
> a = [1,2,3,4,2,2,3,4]> min(a,key=lambda x: a.count(x), default=1) # 求出个数最少的元素1
因为default是可选的,因此还可以这样:
> list=[1,2,5,9,4,6,3]> min(list,key=lambda x:-x) # 取反后最小的值9
再来看一个min函数的用法,求一段文本中出现次数最少的字母。
import stringdef maxcharactor(content):content = content.lower()return min(string.ascii_lowercase, key=content.count)if __name__ == '__main__':print(maxcharactor("/Users/chunming.liu/learn/learn_python_by_coding/learn_string/"))
平时大家更多看到的是这么使用 min 函数,没有key参数:
min([1,2,3,4,2,2,3])
这是因为在min函数说明中,key参数是放在[] 中的,说明它是可选的,可以不传递。
自定义一个函数 func,参数 b 位于 * 后面,只能为关键字参数:
def func(a,*,b):passfunc(a,b=1)f(a,1) # 这种调用是错误的TypeError: f() takes 1 positional argument but 2 were given
再看一个内置函数 sum:
sum(iterable, start=0, /)Return the sum of a 'start' value (default: 0) plus an iterable of numbersWhen the iterable is empty, return the start value.This function is intended specifically for use with numeric values and mayreject non-numeric types.
看到形参列表中有一个 /,它表示 / 前的参数只能是位置参数,不能是关键字参数。
因此,以下调用是合法的:
a = [1,3,2,1,4,2]sum(a,2) # start=2 表示求和的初始值为 215
以下调用是非法的,iterable 参数不能被赋值为关键字实参:
sum(iterable=a,start=2)TypeError: sum() takes no keyword arguments
以后再查看Python中函数用法时,应该可以看懂了吧。
10.5 偏函数functools.partial
Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。
先来看下Python官方的描述:
# content of _functools.pyclass partial(object):"""partial(func, *args, **keywords) - new function with partial applicationof the given arguments and keywords."""pass
翻译过来就是,functools.partial可以给一个函数设置位置参数和关键字参数的默认值,并且返回一个新的可调用对象。之后调用这个新的可调用对象时,就自动带上了functools.partial设置的默认参数值,从而可以传递更少的参数。举个例子:
from functools import partialdef add(a, b, *arg, **kwargs):return a + b, arg, kwargsadd10 = partial(add, 10, kw1=1) # 设置add函数的位置参数a的默认值为10,关键词参数kwargs中的参数kw1的默认值是1,并返回新的可调用对象add10print(add10(11, 12)) # 调用新的函数对象add10,只需要在传递add函数的变量b的值就可以了
用Pycharm调试上面的代码,在add函数的return语句处添加断点,可以看到add10这个对象中args属性里面有一个10,kwwargs里面有一个"kw"=1,这就是通过partial偏函数设置进去的。
当调用add10时,只需要提供变量b=11和arg的值12,add10就能够将其与偏函数设置的值一起传递给原函数add了。
本文分享自微信公众号 - 明说软件测试(liuchunmingnet)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
【API进阶之路】因为不会创建云服务器,我被实习生摆了一道
摘要:9个步骤通过API创建云服务器。 事情是这样的,公司成立了一个新项目,要给项目建官网,并搭建一个web服务器。按照我的习惯,搭建一个本地虚拟机就好了,部署简单方便还好配置,云服务器嘛,写了10年代码,还是不习惯那玩意儿。 我这刚开始动手,就看见实习生屁颠屁颠地跑过来,我心想这小子肯定是想来学虚拟机搭建部署的,这么简单的事都不会,真是白瞎了他那985的学校了。 可是...万万没想到啊,小实习生跑到我老大那里邀功去了!!!远远地听见他说:“公司新项目跑在云服务器上了,以后可以根据访问量随时进行弹性扩展,安全稳定还快。” 啥?云服务器?这小子居然会配置云服务器?听完汇报,老大看向了我,带着小实习生往我这边走过来…… “哼,叫你邀功,撞枪口上了吧,我就说云服务器配置没那么容易,还不是得来找我~”这么想着有点得意,老大走过来拍拍我的肩膀,说:“你跟他学一下怎么配置云服务器,别再用虚拟机了,以后都是麻烦事。” 我...他...让我跟一个实习生学??? 实习生冲我微微一笑,就走了,没过一会扔给我一份文档,上面写着:“创建弹性云服务器流程详解”。打开粗略扫了一眼,代码都直接贴上来了?瞧不起谁?感...
-
下一篇
深入理解Object提供的阻塞和唤醒API
点击上方蓝字 ↑↑ Throwable文摘 关注公众号设置星标,不定时推送高质量原创文章 关注 前提 前段时间花了大量时间去研读JUC中同步器AbstractQueuedSynchronizer的源码实现,再结合很久之前看过的一篇关于Object提供的等待和唤醒机制的JVM实现,发现两者有不少的关联,于是决定重新研读一下Object中提供的阻塞和唤醒方法。本文阅读JDK类库源码使用的JDK版本是JDK11,因此本文内容可能不适合于其他版本。 Object提供的阻塞和唤醒API java.lang.Object作为所有非基本类型的基类,也就是说所有java.lang.Object的子类都具备阻塞和唤醒的功能。下面详细分析Object提供的阻塞和唤醒API,它们有一共共同特点:必须在synchronized所修饰的代码块或者方法中使用。 阻塞等待-wait 等待-wait()方法提供了阻塞的功能,分超时和永久阻塞的版本,实际上,底层只提供了一个JNI方法: //这个是底层提供的JNI方法,带超时的阻塞等待,响应中断,其他两个只是变体publicfinalnativevoidwait(lon...
相关文章
文章评论
共有0条评论来说两句吧...



微信收款码
支付宝收款码