您现在的位置是:首页 > 文章详情

连载|想用Python做自动化测试?Python函数入门

日期:2020-07-20点击:484

 函数是 Python 程序中不可或缺的一部分,它是的程序模块化、清晰化。Python的很多功能都是通过内置函数提供的,比如 sorted() 表示对一个集合序列排序,len() 表示返回一个集合序列的长度大小等等。这节课,我们主要来学习 Python 的自定义函数。

10.1 定义函数

  • 使用def关键字

  • 函数可以有返回值也可以没有返回值

# content of test_sample.pydef 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参数时,必须写明参数名:

>>> 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 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 表示求和的初始值为 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 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,并返回新的可调用对象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源创计划”,欢迎正在阅读的你也加入,一起分享。

原文链接:https://my.oschina.net/u/4589216/blog/4408937
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章