当前位置: 首页 > news >正文

【测试语言篇二】Python进阶篇:lambda函数、异常和错误处理、Json处理、随机数、星号操作符

目录

一、Lambda 函数

使用示例:另一个函数内的Lambda函数

使用lambda函数作为key参数的自定义排序

map 函数中使用 Lambda 函数

filter 函数中使用 Lambda 函数

reduce函数中使用Lambda函数

二、异常和错误

语法错误

异常

抛出异常

处理异常

else 语句

finally 语句

常见的内置异常

如何定义自己的异常

三、JSON

JSON格式

从Python到JSON(序列化,编码)

从JSON到Python(反序列化,解码)

使用自定义对象

编码

解码

模板编码和解码函数

四、随机数

random 模块

种子生成器

secrets 模块

NumPy的随机数

五、星号操作符

乘法和幂运算

创建具有重复元素的列表,元组或字符串

*args, **kwargs 和仅关键字参数

拆包函数参数

拆包容器

将可迭代对象合并到列表中/合并字典


一、Lambda 函数

Python使用lambda来创建匿名函数。

Lambda函数是一个小的(一行)、匿名的、内联函数,没有函数名称。 Lambda函数可以接受任意数量的参数,但只能具有一个表达式

匿名函数不要使用def关键字来定义完整函数。

lambda 函数特点:

  • lambda 函数是匿名的,它们没有函数名称,只能通过赋值给变量或作为参数传递给其他函数来使用。
  • lambda 函数通常只包含一行代码,这使得它们适用于编写简单的函数。
lambda 语法格式:
lambda arguments: expression
  • lambda是 Python 的关键字,用于定义 lambda 函数。
  • arguments 是参数列表,可以包含零个或多个参数,但必须在冒号(:)前指定。
  • expression 是一个表达式,用于计算并返回函数的结果。

当简单函数仅在代码中使用一次或短时间时,可以使用Lambda函数。 最常见的用途是作为高阶函数(将其他函数作为参数的函数)的参数。 它们还与诸如 map(), filter() , reduce()之类的内置函数一起使用。

# 一个给参数加10的lambda函数
f = lambda x: x+10
val1 = f(5)
val2 = f(100)
print(val1, val2)# 一个返回两个参数乘积的lambda函数
f = lambda x,y: x*y
val3 = f(2,10)
val4 = f(7,5)
print(val3, val4)
    15 11020 35

使用示例:另一个函数内的Lambda函数

从另一个函数返回定制的lambda函数,并根据需要创建不同的函数变体。

def myfunc(n):return lambda x: x * ndoubler = myfunc(2)
print(doubler(6))tripler = myfunc(3)
print(tripler(6))
    1218

使用lambda函数作为key参数的自定义排序

key函数会在排序之前转换每个元素。

points2D = [(1, 9), (4, 1), (5, -3), (10, 2)]
sorted_by_y = sorted(points2D, key= lambda x: x[1])
print(sorted_by_y)mylist = [- 1, -4, -2, -3, 1, 2, 3, 4]
sorted_by_abs = sorted(mylist, key= lambda x: abs(x))
print(sorted_by_abs)
    [(5, -3), (4, 1), (10, 2), (1, 9)][-1, 1, -2, 2, -3, 3, -4, 4]

map 函数中使用 Lambda 函数

map(func, seq) ,使用函数转换每个元素。

a  = [1, 2, 3, 4, 5, 6]
b = list(map(lambda x: x * 2 , a))# 但是,尝试使用列表推导
# 如果你已经定义了函数,请使用 map
c = [x*2 for x in a]
print(b)
print(c)numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers)) 
print(squared)
    [2, 4, 6, 8, 10, 12][2, 4, 6, 8, 10, 12][1, 4, 9, 16, 25]

filter 函数中使用 Lambda 函数

filter(func, seq) ,返回其 func 计算为 True 的所有元素。

#使用 lambda 函数与 filter() 一起,筛选偶数:
a = [1, 2, 3, 4, 5, 6, 7, 8]
b = list(filter(lambda x: (x%2 == 0) , a))# 同样可以使用列表推导实现
c = [x for x in a if x%2 == 0]
print(b)
print(c)
    [2, 4, 6, 8][2, 4, 6, 8]

reduce函数中使用Lambda函数

reduce(func, seq) ,重复将 func 应用于元素并返回单个值。func 需要2个参数。

from functools import reduce
numbers = [1, 2, 3, 4, 5]
product_a = reduce(lambda x, y: x*y, numbers)
print(product_a)
sum_a = reduce(lambda x, y: x+y, numbers)
print(sum_a)
    12015
在上面的实例中,reduce() 函数通过遍历 numbers 列表,并使用 lambda 函数将累积的结果不断更新,最终得到了 1 * 2 * 3 * 4 * 5 = 120 的结果。

二、异常和错误

Python程序在遇到错误后立即终止。在Python中,错误可以是语法错误或异常。 在本文中,我们将关注以下内容:

  • 语法错误与异常

  • 如何抛出异常

  • 如何处理异常

  • 常见的内置异常

  • 如何定义自己的异常

语法错误

当解析器检测到语法不正确的语句时发生语法错误。 语法错误可以是例如拼写错误,缺少括号,没有新行(请参见下面的代码)或错误的标识(这实际上会引发它自己的IndentationError,但它是SyntaxError的子类)。

a = 5 print(a)
    File "<ipython-input-5-fed4b61d14cd>", line 1a = 5 print(a)^SyntaxError: invalid syntax

异常

即使一条语句在语法上是正确的,执行该语句也可能导致错误,这称为 异常错误。 有几种不同的错误类别,例如,尝试对数字和字符串求和将引发 TypeError

a = 5 + '10'
    ---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-6-893398416ed7> in <module>----> 1 a = 5 + '10'TypeError: unsupported operand type(s) for +: 'int' and 'str'

抛出异常

如果要在满足特定条件时强制发生异常,则可以使用 raise 关键字。

x = -5
if x < 0:raise Exception('x should not be negative.')
    ---------------------------------------------------------------------------Exception                                 Traceback (most recent call last)<ipython-input-4-2a9e7e673803> in <module>1 x = -52 if x < 0:----> 3     raise Exception('x should not be negative.')Exception: x should not be negative.

你还可以使用 assert 语句,如果你的断言不是 True,则将引发 AssertionError。 这样,你可以主动测试必须满足的某些条件,而不必等待程序中途崩溃。 断言还用于单元测试

x = -5
assert (x >= 0), 'x is not positive.'
# --> 如果 x >= 0,代码将正常运行
    ---------------------------------------------------------------------------AssertionError                            Traceback (most recent call last)<ipython-input-7-f9b059c51e45> in <module>1 x = -5----> 2 assert (x >= 0), 'x is not positive.'3 # --> Your code will be fine if x >= 0AssertionError: x is not positive.

处理异常

你可以使用 try 和 except 块来捕获和处理异常。 如果你可以捕获异常,则你的程序将不会终止,并且可以继续。

# 这将捕获所有可能的异常
try:a = 5 / 0
except:print('some error occured.')# 可以捕获异常类型
try:a = 5 / 0
except Exception as e:print(e)# 最好指定要捕获的异常类型
# 因此,你必须知道可能的错误
try:a = 5 / 0
except ZeroDivisionError:print('Only a ZeroDivisionError is handled here')# 你可以在try块中运行多个语句,并捕获不同的可能的异常
try:a = 5 / 1 # 注意:这里没有 ZeroDivisionErrorb = a + '10'
except ZeroDivisionError as e:print('A ZeroDivisionError occured:', e)
except TypeError as e:print('A TypeError occured:', e)
    Some error occured.Division by zeroOnly a ZeroDivisionError is handled hereA TypeError occured: unsupported operand type(s) for +: 'float' and 'str'

else 语句

如果没有发生异常,则可以使用else语句运行。

try:a = 5 / 1
except ZeroDivisionError as e:print('A ZeroDivisionError occured:', e)
else:print('Everything is ok')
    Everything is ok

finally 语句

你可以使用始终运行的 finally 语句,无论是否存在异常。 例如,这可用于进行一些清理操作。

try:a = 5 / 1 # 注意:这里没有 ZeroDivisionErrorb = a + '10'
except ZeroDivisionError as e:print('A ZeroDivisionError occured:', e)
except TypeError as e:print('A TypeError occured:', e)
else:print('Everything is ok')
finally:print('Cleaning up some stuff...')
    A TypeError occured: unsupported operand type(s) for +: 'float' and 'str'Cleaning up some stuff...

常见的内置异常

你可以在此处找到所有内置的异常:https://docs.python.org/3/library/exceptions.html

  • ImportError:如果无法导入模块

  • NameError:如果你尝试使用未定义的变量

  • FileNotFoundError:如果你尝试打开一个不存在的文件或指定了错误的路径

  • ValueError:当某个操作或函数收到类型正确但值不正确的参数时,例如尝试从不存在的列表中删除值

  • TypeError:将操作或函数应用于不适当类型的对象时引发。

  • IndexError:如果你尝试访问序列的无效索引,例如列表或元组。

  • KeyError:如果你尝试访问字典中不存在的键。

# ImportError
import nonexistingmodule# NameError
a = someundefinedvariable# FileNotFoundError
with open('nonexistingfile.txt') as f:read_data = f.read()# ValueError
a = [0, 1, 2]
a.remove(3)# TypeError
a = 5 + "10"# IndexError
a = [0, 1, 2]
value = a[5]# KeyError
my_dict = {"name": "Max", "city": "Boston"}
age = my_dict["age"]

如何定义自己的异常

你可以定义自己的异常类,该异常类应从内置的 Exception 类派生。 与标准异常的命名类似,大多数异常都以“错误”结尾的名称定义。 可以像定义其他任何类一样定义异常类,但是它们通常保持简单,通常仅提供一定数量的属性,这些属性允许处理程序提取有关错误的信息。

# 自定义异常类的最小示例
class ValueTooHighError(Exception):pass# 或者为处理者添加一些信息
class ValueTooLowError(Exception):def __init__(self, message, value):self.message = messageself.value = valuedef test_value(a):if a > 1000:raise ValueTooHighError('Value is too high.')if a < 5:raise ValueTooLowError('Value is too low.', a) # 注意,构造器接受两个参数return atry:test_value(1)
except ValueTooHighError as e:print(e)
except ValueTooLowError as e:print(e.message, 'The value is:', e.value)
    Value is too low. The value is: 1

三、随机数

Python定义了一组用于生成或操作随机数的函数。 本文介绍:

  • random 模块

  • 用 random.seed() 再生产数字

  • 使用 secrets 模块创建密码学上强的随机数

  • 用 numpy.random 创建随机 nd 数组

random 模块

该模块为各种版本实现伪随机数生成器。它使用Mersenne Twister算法(https://en.wikipedia.org/wiki/Mersenne_Twister)作为其核心生成器。 之所以称其为伪随机数,是因为数字看起来是随机的,但是是可重现的。

import random# [0,1) 之间随机浮点数
a = random.random()
print(a)# [a,b] 之间随机浮点数
a = random.uniform(1,10)
print(a)# [a,b] 之间随机整数,b 包括。
a = random.randint(1,10)
print(a)# 之间随机整数,b 不包括。
a = random.randrange(1,10)
print(a)# 参数为 mu 和 sigma 的正态分布随机浮点数
a = random.normalvariate(0, 1)
print(a)# 从序列中随机选择元素
a = random.choice(list("ABCDEFGHI"))
print(a)# 从序列中随机选择 k 个唯一元素
a = random.sample(list("ABCDEFGHI"), 3)
print(a)# 选择可重复的k个元素,并返回大小为k的列表
a = random.choices(list("ABCDEFGHI"),k=3)
print(a)# 原地随机排列
a = list("ABCDEFGHI")
random.shuffle(a)
print(a)
    0.104263734520673173.3498397935244434-1.004568769635799E['G', 'C', 'B']['E', 'D', 'E']['D', 'I', 'G', 'H', 'E', 'B', 'C', 'F', 'A']

种子生成器

使用 random.seed(),可以使结果可重复,并且 random.seed() 之后的调用链将产生相同的数据轨迹。 随机数序列变得确定,或完全由种子值确定。

print('Seeding with 1...\n')random.seed(1)
print(random.random())
print(random.uniform(1,10))
print(random.choice(list("ABCDEFGHI")))print('\nRe-seeding with 42...\n')
random.seed(42)  # 重设随机种子print(random.random())
print(random.uniform(1,10))
print(random.choice(list("ABCDEFGHI")))print('\nRe-seeding with 1...\n')
random.seed(1)  # 重设随机种子print(random.random())
print(random.uniform(1,10))
print(random.choice(list("ABCDEFGHI")))print('\nRe-seeding with 42...\n')
random.seed(42)  # 重设随机种子print(random.random())
print(random.uniform(1,10))
print(random.choice(list("ABCDEFGHI")))
    Seeding with 1...0.134364244112401228.626903632435095BRe-seeding with 42...0.63942679845788371.2250967970040025ERe-seeding with 1...0.134364244112401228.626903632435095BRe-seeding with 42...0.63942679845788371.2250967970040025E

secrets 模块

secrets 模块用于生成适合于管理数据(例如密码,帐户身份验证,安全令牌和相关机密)的密码学上强的随机数。

特别是,应优先使用secrets 而不是 random 模块中默认的伪随机数生成器,后者是为建模和仿真而设计的,而不是安全或加密技术。

import secrets# [0, n) 之间的随机整数。
a = secrets.randbelow(10)
print(a)# 返回具有k个随机位的整数。
a = secrets.randbits(5)
print(a)# 从序列中选择一个随机元素
a = secrets.choice(list("ABCDEFGHI"))
print(a)
    66E

NumPy的随机数

为多维数组创建随机数。NumPy伪随机数生成器与Python标准库伪随机数生成器不同。

重要的是,设置Python伪随机数生成器种子不会影响NumPy伪随机数生成器,必须单独设置和使用。

import numpy as npnp.random.seed(1)
# rand(d0,d1,…,dn)
# 生成随机浮点数的多维数组, 数组大小为 (d0,d1,…,dn)
print(np.random.rand(3))
# 重设随机种子
np.random.seed(1)
print(np.random.rand(3))# 生成 [a,b) 之间随机整数的多维数组,大小为 n
values = np.random.randint(0, 10, (5,3))
print(values)# 使用正态分布值生成多维数组,数组大小为 (d0,d1,…,dn)
# 来自标准正态分布的平均值为0.0且标准偏差为1.0的值
values = np.random.randn(5)
print(values)# 随机排列一个多维数组.
# 仅沿多维数组的第一轴随机排列数组
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
np.random.shuffle(arr)
print(arr)
    [4.17022005e-01 7.20324493e-01 1.14374817e-04][4.17022005e-01 7.20324493e-01 1.14374817e-04][[5 0 0][1 7 6][9 2 4][5 2 4][2 4 7]][-2.29230928 -1.41555249  0.8858294   0.63190187  0.04026035][[4 5 6][7 8 9][1 2 3]]

四、星号操作符

星号( * )可用于Python中的不同情况:

  • 乘法和幂运算

  • 创建具有重复元素的列表,元组或字符串

  • *args, **kwargs 和仅关键字参数

  • 拆包列表/元组/字典的函数参数

  • 拆包容器

  • 将可迭代对象合并到列表中/合并字典

乘法和幂运算

# 乘法
result = 7 * 5
print(result)# 幂运算
result = 2 ** 4
print(result)
    3516

创建具有重复元素的列表,元组或字符串

# list
zeros = [0] * 10
onetwos = [1, 2] * 5
print(zeros)
print(onetwos)# tuple
zeros = (0,) * 10
onetwos = (1, 2) * 5
print(zeros)
print(onetwos)# string
A_string = "A" * 10
AB_string = "AB" * 5
print(A_string)
print(AB_string)
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0][1, 2, 1, 2, 1, 2, 1, 2, 1, 2](0, 0, 0, 0, 0, 0, 0, 0, 0, 0)(1, 2, 1, 2, 1, 2, 1, 2, 1, 2)AAAAAAAAAAABABABABAB

*args, **kwargs 和仅关键字参数

  • 对可变长度参数使用 *args

  • 对长度可变的关键字参数使用 **kwargs

  • 使用 *,后跟更多函数参数以强制使用仅关键字的参数

def my_function(*args, **kwargs):for arg in args:print(arg)for key in kwargs:print(key, kwargs[key])my_function("Hey", 3, [0, 1, 2], name="Alex", age=8)# '*' 或 '* identifier' 之后的参数是仅关键字参数,只能使用关键字参数传递。
def my_function2(name, *, age):print(name)print(age)# my_function2("Michael", 5) --> 这会引发 TypeError 错误
my_function2("Michael", age=5)
    Hey3[0, 1, 2]name Alexage 8Michael5

拆包函数参数

  • 如果长度与参数匹配,则列表/元组/集合/字符串可以用 * 拆成函数参数。

  • 如果长度和键与参数匹配,则字典可以用两个 ** 拆包。

def foo(a, b, c):print(a, b, c)# 长度必需匹配
my_list = [1, 2, 3]
foo(*my_list)my_string = "ABC"
foo(*my_string)# 长度和键必需匹配
my_dict = {'a': 4, 'b': 5, 'c': 6}
foo(**my_dict)
    1 2 3A B C4 5 6

拆包容器

将列表,元组或集合的元素拆包为单个和多个剩余元素。 请注意,即使被拆包的容器是元组或集合,也将多个元素组合在一个列表中。

numbers = (1, 2, 3, 4, 5, 6, 7, 8)*beginning, last = numbers
print(beginning)
print(last)print()first, *end = numbers
print(first)
print(end)print()
first, *middle, last = numbers
print(first)
print(middle)
print(last)
    [1, 2, 3, 4, 5, 6, 7]81[2, 3, 4, 5, 6, 7, 8]1[2, 3, 4, 5, 6, 7]8

将可迭代对象合并到列表中/合并字典

由于PEP 448(PEP 448 – Additional Unpacking Generalizations | peps.python.org),从Python 3.5开始,这是可能的。

# 将可迭代对象合并到列表中
my_tuple = (1, 2, 3)
my_set = {4, 5, 6}
my_list = [*my_tuple, *my_set]
print(my_list)# 用字典拆包合并两个字典
dict_a = {'one': 1, 'two': 2}
dict_b = {'three': 3, 'four': 4}
dict_c = {**dict_a, **dict_b}
print(dict_c)
    [1, 2, 3, 4, 5, 6]{'one': 1, 'two': 2, 'three': 3, 'four': 4}

但是,请注意以下合并解决方案。 如果字典中有任何非字符串键,则它将不起作用:https://stackoverflow.com/questions/38987/how-to-merge-two-dictionaries-in-a-single-expression/39858#39858

dict_a = {'one': 1, 'two': 2}
dict_b = {3: 3, 'four': 4}
dict_c = dict(dict_a, **dict_b)
print(dict_c)# 以下可行:
# dict_c = {**dict_a, **dict_b}
---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-52-2660fb90a60f> in <module>1 dict_a = {'one': 1, 'two': 2}2 dict_b = {3: 3, 'four': 4}----> 3 dict_c = dict(dict_a, **dict_b)4 print(dict_c)5 TypeError: keywords must be strings

推荐进一步阅读:

  • https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/

  • https://treyhunner.com/2016/02/how-to-merge-dictionaries-in-python/


http://www.mrgr.cn/news/67530.html

相关文章:

  • 非关系型数据库NoSQL的类型与优缺点对比
  • 点云分割总结
  • 如何使用Netdata部署高性能的服务器监控平台
  • Linux系列-进程的属性
  • 【spring】Cookie和Session的设置与获取(@CookieValue()和@SessionAttribute())
  • 【笔记】变压器-热损耗-频响曲线推导 - 02 预备知识
  • 钉钉调试微应用整理2
  • 海云安入选软件供应链安全十大代表厂商,软件供应链安全创新成果获认可
  • (十四)JavaWeb后端开发——MyBatis
  • 【Python】轻松解析JSON与XML:Python标准库的json与xml模块
  • 深度学习经典模型之Network in Network
  • 【单例模式】饿汉式与懒汉式以及线程安全
  • 嵌入向量模型与BM25算法结合:并行检索获取多种结果
  • 常见几种GB 9706.1-2020医疗器械试验工装,您有所了解吗?
  • 使用stream遍历对象集合,取出所有对象的某字段,并以逗号拼接起来
  • 【TabBar嵌套Navigation案例-常见问题按钮-WebView-加载JavaScript Objective-C语言】
  • 杭州电商运营公司排名:怎么找到适合自己的电商代运营公司
  • Java基础知识
  • 模拟计算机如何识别和执行机器语言指令:从虚拟CPU的角度解析
  • C#-哈希表
  • 七载同行,共襄盛会!苏州金龙高标准服务进博会彰显中国智造风采
  • Java手写二分查找
  • 部署一个属于自己的文件服务器(File Browser )
  • 使用亚马逊 S3 连接器为 PyTorch 和 MinIO 创建地图式数据集
  • Halcon 算法加速的基础知识(多核并行/GPU)
  • 多任务学习在转转主搜精排的应用