Python接口自动化测试框架(基础篇)-- 函数与内置函数

简介: 本文详细介绍了Python中的函数概念,包括自定义函数、参数传递、局部与全局变量,以及内置函数的使用,还扩展了匿名函数、return和yield、exec()、vars()、iter()、map()、zip()、reversed()和sorted()等高级函数和概念。

前言

函数在前面的基础部分频繁出现,更有多次演示,多是数据类型的相关函数或是python内建函数(不需要自己定义的);这章会重点讲自己怎么写函数,即自定义函数。

image.png

函数

一个问题,什么是函数?

函数是有组织、有目的,可重复使用的,即提高代码复用率的功能代码块;关键字是def 函数名(如果有参数): Pass

image.png

自定义函数

def hello():
    print("Hello World!")

hello() # 调用函数,输出内容会打印在控制台:Hello World!

print(hello())  
# 会输出print的内容到控制台,同时还有一个None
  • 思考一下,为啥print(函数())会有一个None?
参数传递

这里先简单介绍一下参数有哪些名词:形参、实参、默认参数、不定长参数、关键字参数、必须参数,位置参数

  • 形参:就是在定义函数时的参数,如:def func(a): pass那么a就是形式参数
  • 必须参数:延续上面的例子,如果调用函数func()不传参数就会报错,这时a就是必须参数
  • 实参:既然不传参数会报错,那么就给个参数:func(1),这时1就是实际传入func的参数,实参
  • 位置参数: 意思是调用函数时指定参数并传值,这样参数就跟定义函数时的位置没有关系了
def func(a,b):
    return a+b

print(func(b=2,a=1)) # 输出:3

# 如果不使用位置参数指定入参,那么a和b的值就会不一样。
print(func(2,1)) # 这时函数内部,a=2,b=1
  • 默认参数:很好理解,就是定义函数时带参数,并且给参数一个值,那么在调用时可以选择不传参也不会报错
  • 不定长参数:又叫动态参数/可变参数;用于不知道函数具体要传多少参数及参数类型,一般有两种使用方式*argsb表示和**kwargs

def func(a,b,c=None,*args,**kwargs):
    print("第一个参数a:"+a)
    print("第二个参数b:"+b)
    print("第三个参数c:"+c)
    print("第四个参数args:"+args)
    print("第五个参数kwargs:"+kwargs)
    pass

func(a=1,c=3,b=2,*("a","v","c"),key="value1",k="value2")
变量
  • 什么是变量?
在于变。即在程序运行过程中可能发生变化的量;如:a初始为0,随着程序运行最终a变成了1或非0的值,那么a就是变量;注意:a在使用中才会创建的变量,即给它分配内存空间。
  • 既然说到变量,就不得不说一下局部变量跟全局变量
# 局部变量为当前代码块或循环中的变量,它不能被它以外的事务请求

>>> def func():
...     a=1
...     b=2
...     return a+b
...
>>> func()
3
>>> print(a)  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

# 当输入a变量时,则会报错,提示a没有被定义
    • 全局变量
# 相反,定义在代码块以外的变量称之为全局变量,它可以在当前py模块中任意位置调用,但是不能在它未被申明之前

>>> a = 1
>>> def func(a):
...     a = a+1
...     return a
...
>>> func(a)
2
>>> print(a)  # 函数内的a是变了,但是外面的a没有变
1
  • global关键字,定义全局变量
# 如下这种情况,a不是全局变量,因为func()函数用的不是外面的a
>>> a = 1
>>> def func():
...     a = 2
...     return a
...
>>> func()
2
>>> print(a)
1
    • 使用关键字global使func函数内的a成为全局变量,那么它在外面调用就应该是func所改变的a
>>> a = 1
>>> def func():
...     global a
...     a = 2
...     return a
...
>>> func()
2
>>> print(a)
2
内置函数

不需要引用也不需要定义就能直接使用的函数,这里特别介绍几个常用的内置函数

  • 常用数据类型就是最基础的内置函数:str()、dict()、list()、bool()等等
  • eval() # 执行字符串的表达式,并返回它的结果
>>> eval("5*3")
15
  • input()和print() # 输入输出
  • range() # 一般与for循环搭配使用,创建list或遍历
# 注意一下:这只能是迭代对象,而不是迭代器
res0=range(9) #可迭代对象
print("内置函数range():{}".format(list(res)))

# 支持步长取值
range(n,m,k)
#n为起点,默认为0,m为终点,k为步长即公差
  • type() # 获取变量或数据的数据类型
lis1=[1,2,3,4,5,6]
cls_str=type(lis1)
print("查询数据类型:{}".format(cls_str))
  • isinstance() # 判断数据类型,返回结果为True或者False
示例1:
# 可以比较数据类型,及类类型type
class TestClsA(unittest.TestCase):
    """
    定义一个类,随便选一个类继承;
    作用:1.给类属性相关函数使用;
      2.其他内置函数对比类型。
    """
    pass

class TestClsB(TestClsA):
    """同上,如果该初始化对象,则对象类型与上一个类类型一致"""
    pass

#初始化对象
test=TestClsA()
test1=TestClsB()

lis2=[2,3,4,5,6,7]

res4=isinstance(lis2, (list,tuple)) #第二参数可以是类型组成的元组
res5=isinstance(test,unittest.TestCase)# 对象类型是上级的类
res6=isinstance(test1,(unittest.TestCase,TestClsA))# 对象类型是上上级的类型
print("比较数据类型:{},及对象类型:{}".format(res5,res6))


示例2:
# 判断是否是迭代器

# from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections.abc import Iterable,Iterator
# 可以判断对象是否为可迭代对象
a=isinstance([], Iterable)
print("true为可迭代对象{}".format(a))
b=isinstance(iter([]), Iterator)
print("true可迭代对象为迭代器{}".format(b))
  • enumerate() # 将可遍历的数据类型组合为一个索引序列
示例1>>> list(enumerate(("a","b","c")))
[(0, 'a'), (1, 'b'), (2, 'c')]


示例2# 初始化一个list数据类型
lis1=[1,2,4,3,5]
#第一个参数是 一个序列、迭代器或其他支持迭代对象。第二参数指定起始位置,默认为0
res=list(enumerate(lis1))
print("enumerate返回的是枚举对象(计数值,元素值):{}".format(res))
# 应用场景:获取可迭代对象的下标与元素值组成元组元素的list

for k,v in enumerate(lis1):
    print("enumerate高级用法,拆包list种的元组元素【{},{}】".format(k,v))
  • id() # 获取变量在内存中的地址;
# 返回对象的“标识值”,整数,理解成对象地址

a=1
b=1
c=a
if id(a)==id(c) and id(c)==id(b):
    print("比较对象指向的内存地址")
if a==b:
    print("比较变量a与b的值")
  • open() # 用于文件IO操作
  • sum() # 求和
lis13=[1,3,7,9,0,5]
total=sum(lis13)
print("快速求和:{}".format(total))
  • len() # 求序列数据类型的长度
lis6=[1,3,4,4,6,7]
length=len(lis6)
print("获取数据类型{}的长度:{}".format(lis6,length))
  • min()和max() # 最大或最小值
# 最大
lis5=(2,3,4,4,6,7)
res_max=max(lis5)
print("获取是int类型的可迭代对象:{},的最大值:{}".format(lis5,res_max))

# 最小
res_min=min(lis5)
print("获取是int类型的可迭代对象:{},的最小值:{}".format(lis5,res_min))
  • all()和any() # 可迭代参数,判断元素中不能有0或空字符或None元素的数据;但是空列表却是True
>>> a = 1
>>> b = 0
>>> all([a,b])
False
>>> all([a])
True
  • filter()
# 返回的是一个迭代器,可以被list、tuple接收

# filter(function, iterable) 相当于一个生成器表达式,
# 当 function 不是 None 的时候为 (item for item in iterable if function(item));
# function 是 None 的时候为 (item for item in iterable if item) 。
# lambda 匿名函数的使用
res1=filter(lambda x:x>3,lis1)
print("filter条件过滤,返回后结果:{}".format(list(res1)))
  • round() # 数值求整数
z_n=round(3.11233,3)#int是取整,round取float保留几位小数
print("小数点取整:{}".format(z_n))
  • format() # 格式化输出函数不解释

扩展

匿名函数
  • lambda,它是一个表达式,比def定义的函数体要简单的多;所以它本身只能是一行代码表示,且逻辑有限,返回的的是:冒号后面的结果
>>> create_list = lambda x:[i for i in range(x)]
>>> create_list(4)
[0, 1, 2, 3]
>>>
>>> sum_x = lambda a,b:a+b
>>> sum_x(3,5)
8
return和yield
  • return 每个def定义的函数,都有一个默认的return,后面没有东西,print它是个None
# 对比一下两个函数
>>> def func():
...     print(1)
...
>>> func()
1
>>> print(func())
1
None
>>> 
>>> 
>>> def func():
...     print("输出1")
...     return "修改了默认输出"
...
>>> print(func())
输出1
修改了默认输出
  • yield在python是个特殊用法,函数使用了yield就叫生成器;比较特别,它会在第一个使用它并且记住它,到第二次使用时就进入下一个值,可以说是迭代器
# 引入runoob.com的代码示例:

#!/usr/bin/python3

import sys

def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成

while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

# yield实现斐波那契数列:
# 输出:0 1 1 2 3 5 8 13 21 34 55
exec(object)

object 必须是字符串或者代码对象(表达式)

# 函数支持动态执行 Python 代码
exec("print('动态执行python代码:{}'.format(1+3))")
vars()

返回模块、类、实例或任何其它具有 dict 属性的对象的 dict 属性。

class TestA:
    pass

a=TestA()

print(vars(a))

结果输出如下:

{
   
   '_testMethodName': 'runTest', '_outcome': None, '_testMethodDoc': 'No test', '_cleanups': [], '_subtest': None, '_type_equality_funcs': {
   
   <class 'dict'>: 'assertDictEqual', <class 'list'>: 'assertListEqual', <class 'tuple'>: 'assertTupleEqual', <class 'set'>: 'assertSetEqual', <class 'frozenset'>: 'assertSetEqual', <class 'str'>: 'assertMultiLineEqual'}}
iter()迭代器

获取可迭代对象的迭代器,iter()函数实际上就是调用了可迭代对象的__iter__方法。

lis3=[1,3,4,4,6,7]
res6=iter(lis3) # 返回的是一个迭代器
print("用list接收:{}".format(list(res6))) #用list接收
lis4=[1,3,4,4,6,7]
res6=iter(lis4)
print("用tuple接收:{}".format(tuple(res6))) #用tuple接收

使用next()函数来获取iter()迭代器的下一条数据

lis5=[1,3,4,4,6,7]
res6=iter(lis5)
while 1:
    try:
        v=next(res6)
    except StopIteration as e:
        print("遇到StopIteration迭代取值完成")
        break
    else:
        print("next获取迭代器的数据:{}".format(v))
map()

返回的是一个迭代器,可以用list/tuple来接收,

lis7=[1,3,4,4,6,7]
res7=map(lambda x:x+1,lis7)
print("{}数据类型,map函数返回一个迭代器:{}".format(lis7,res7))
# 遍历map返回的迭代器的新的元素值
for i in res7:
    print("遍历出迭代器{}的值:{}".format(res7,i))
zip()

返回是迭代器,可以用list/tuple来接收,同样next()取值

lis8=[2,3,7,9,0,1]
lis9=[1,3,4,4,6]
res9=zip(lis8,lis9) # 打包为元组的列表,
# 元素个数与最短的列表一致,即会抛开元素个数多的那几个
print("内置打包函数zip:{},list接收:{}".format(res9,list(res9)))
reversed()
lis10=[1,3,7,9,0,5]
revers_li=reversed(lis10)
print("反转:{}".format(list(revers_li)))
sorted()列表排序
lis11=[1,3,7,9,0,5]
bubble=sorted(lis11,reverse=True)#reverse=True降序,默认倒序
print("排序:{}".format(bubble))
相关文章
|
5天前
|
测试技术 数据库 UED
Python 性能测试进阶之路:JMeter 与 Locust 的强强联合,解锁性能极限
【9月更文挑战第9天】在数字化时代,确保软件系统在高并发场景下的稳定性至关重要。Python 为此提供了丰富的性能测试工具,如 JMeter 和 Locust。JMeter 可模拟复杂请求场景,而 Locust 则能更灵活地模拟真实用户行为。结合两者优势,可全面评估系统性能并优化瓶颈。例如,在电商网站促销期间,通过 JMeter 模拟大量登录请求并用 Locust 模拟用户浏览和购物行为,可有效识别并解决性能问题,从而提升系统稳定性和用户体验。这种组合为性能测试开辟了新道路,助力应对复杂挑战。
20 2
|
1天前
|
SQL JavaScript 前端开发
基于Python访问Hive的pytest测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Python、来开发Hive应用的方法,产生的代码如下
12 6
基于Python访问Hive的pytest测试代码实现
|
5天前
|
数据采集 人工智能 程序员
避坑指南!细说Python自动化办公的5大缺点
Python如今变得愈发流行,不仅程序员,许多非专业人员也开始学习它,主要目的是提高工作效率而非成为专家。然而,Python自动化办公并非完美,存在一些缺点:首先,它仅支持Windows系统,这对Mac用户不太友好;其次,其功能虽强大但不够专业,大多功能一行代码即可完成;再者,代码包体积较大,约200MB;此外,技术门槛较低,难以形成职业优势;最后,相较于专业代码,它的启动速度较慢。即便如此,它依然比人工操作高效得多。如果能接受以上缺点,可参考《50讲·Python自动化办公》教程,快速掌握自动化办公技能。
46 29
|
4天前
|
安全 JavaScript 前端开发
自动化测试的魔法:如何用Python编写你的第一个测试脚本
【8月更文挑战第41天】在软件的世界里,质量是王道。而自动化测试,就像是维护这个王国的骑士,确保我们的软件产品坚不可摧。本文将引导你进入自动化测试的奇妙世界,教你如何使用Python这把强大的魔法杖,编写出能够守护你代码安全的第一道防护咒语。让我们一起开启这场魔法之旅吧!
|
9天前
|
测试技术 API Python
python在自动化测试中的经典例子
python在自动化测试中的经典例子
23 12
|
4天前
|
测试技术 持续交付 Apache
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
【9月更文挑战第10天】随着软件应用的不断扩展,性能测试成为确保系统稳定运行的关键环节。本文通过对比Apache JMeter和Locust,探讨了如何在Python环境中利用这两款工具挖掘更多性能测试潜力。JMeter是一款成熟且功能强大的开源工具,支持多种协议,适用于各种应用的测试;而Locust则基于Python,通过简单脚本模拟HTTP请求,更适合Web应用测试。
13 2
|
9天前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
【9月更文挑战第5天】性能测试是确保应用在高负载下稳定运行的关键。本文介绍Apache JMeter和Locust两款常用性能测试工具,帮助识别并解决性能瓶颈。JMeter适用于测试静态和动态资源,而Locust则通过Python脚本模拟HTTP请求。文章详细讲解了安装、配置及使用方法,并提供了实战案例,帮助你掌握性能测试技巧,提升应用性能。通过分析测试结果、模拟并发、检查资源使用情况及代码优化,确保应用在高并发环境下表现优异。
35 5
|
6天前
|
消息中间件 监控 测试技术
惊呆了!Python性能测试高手都用这些神器:JMeter+Locust,效率翻倍📈
【9月更文挑战第8天】在软件开发中,性能测试对确保应用稳定性和高效运行至关重要。对于Python开发者而言,选择合适的性能测试工具能显著提升测试效率并精准定位性能瓶颈。本文深入探讨了JMeter和Locust这两款工具的独特优势。JMeter作为跨平台的性能测试工具,支持多种协议,具备高度可定制性和扩展性;而Locust则专为Python应用设计,利用协程实现高并发,提供实时监控和分布式测试功能。两者结合使用,可在实际项目中实现1+1&gt;2的效果,帮助开发者构建全面高效的测试方案,保障应用稳定运行。
30 1
|
7天前
|
运维 监控 API
自动化运维:使用Python脚本进行日常管理
【9月更文挑战第6天】在现代的IT环境中,自动化运维已成为提升效率、减少人为错误的关键。本文将介绍如何通过Python脚本简化日常的运维任务,包括批量配置管理和日志分析。我们将从基础语法讲起,逐步深入到脚本的实际应用,旨在为读者提供一套完整的解决方案,以实现运维工作的自动化和优化。
11 1
|
8天前
|
测试技术 Apache 数据库
从慢如蜗牛到飞一般的感觉!Python性能测试实战,JMeter&Locust助你加速🏃‍♂️
【9月更文挑战第6天】你的Python应用是否曾因响应缓慢而让用户望而却步?借助JMeter与Locust,这一切将迎刃而解。JMeter作为Apache基金会的明星项目,以其强大的跨平台和多协议支持能力,成为性能测试领域的魔法师;而Locust则以Python的简洁与高效,让性能测试更加灵活。通过实战演练,你可以利用这两款工具轻松识别并解决性能瓶颈,优化数据库查询、网络配置等,最终使应用变得敏捷高效,轻松应对高并发挑战。
11 1