连载|想用Python做自动化测试?Python函数入门
“ 函数是 Python 程序中不可或缺的一部分,它是的程序模块化、清晰化。Python的很多功能都是通过内置函数提供的,比如 sorted() 表示对一个集合序列排序,len() 表示返回一个集合序列的长度大小等等。这节课,我们主要来学习 Python 的自定义函数。”
10.1 定义函数
使用def关键字
函数可以有返回值也可以没有返回值
# content of test_sample.py
def inc(x): # 有返回值
return x + 1
def 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 = 0
for n in numbers:
sum = sum + n * n
return 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]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the 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 the
reverse 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]) -> value
min(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its smallest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the smallest argument.
"""
pass
min 函数的源码文档中,举了两个例子,其中的形参有 *
符号,又有 []
?他们都表示啥意思呢?
函数形参列表中符号 *
表示,后面的形参只能为关键字参数,不能为位置参数,[]里面的参数是可选的,不是必填的,例如传递一个key参数和default参数时,必须写明参数名:
1,2,3,4,2,2,3,4] > a = [
x: a.count(x), default=1) # 求出个数最少的元素 > min(a,key=lambda
1
因为default是可选的,因此还可以这样:
1,2,5,9,4,6,3] > list=[
x:-x) # 取反后最小的值 > min(list,key=lambda
9
再来看一个min函数的用法,求一段文本中出现次数最少的字母。
import string
def 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):
pass
func(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 numbers
When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
看到形参列表中有一个 /
,它表示 /
前的参数只能是位置参数,不能是关键字参数。
因此,以下调用是合法的:
a = [1,3,2,1,4,2]
sum(a,2) # start=2 表示求和的初始值为 2
15
以下调用是非法的,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.py
class partial(object):
"""
partial(func, *args, **keywords) - new function with partial application
of the given arguments and keywords.
"""
pass
翻译过来就是,functools.partial可以给一个函数设置位置参数和关键字参数的默认值,并且返回一个新的可调用对象。之后调用这个新的可调用对象时,就自动带上了functools.partial设置的默认参数值,从而可以传递更少的参数。举个例子:
from functools import partial
def add(a, b, *arg, **kwargs):
return a + b, arg, kwargs
add10 = partial(add, 10, kw1=1) # 设置add函数的位置参数a的默认值为10,关键词参数kwargs中的参数kw1的默认值是1,并返回新的可调用对象add10
print(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条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7设置SWAP分区,小内存服务器的救世主