Python Relearing-Function/lambda/re
函数
return 语句
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None。
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10**,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
可变类型:变量赋值la=[1,2,3,4]后再赋值la[2]=5则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
可变类型:类似C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13#!/usr/bin/python3
# 可写函数说明
def changeme( mylist ):
"修改传入的列表"
mylist.append([1,2,3,4])
print ("函数内取值: ", mylist)
return
# 调用changeme函数
mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)结果如下:
1
2函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]
强制位置参数
Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。
在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:
1
2def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)以下使用方法是正确的:
1
f(10, 20, 30, d=40, e=50, f=60)
以下使用方法会发生错误:
# b 不能使用关键字参数的形式f(10, b=20, c=30, d=40, e=50, f=60)# e 必须使用关键字参数的形式``f(10, 20, 30, 40, 50, f=60)可变参数
1
2def fun(*args):
# 函数操作例如:
1 | def calc(*numbers): |
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
1 | calc(1, 2) |
如果已经有一个list或者tuple,要调用一个可变参数,可以加上*,
方法一:
1
2
3nums = [1, 2, 3]
calc(nums[0], nums[1], nums[2])
14方法二
1 | >>> nums = [1, 2, 3] |
*nums表示把nums这个list的所有元素作为可变参数传进去。
关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
1 | def person(name, age, **kw): |
调用1
1 | >>>person('Michael', 30) |
调用2
1 | >>>person('Bob', 35, city='Beijing') |
把组装好的字典作为关键字参数传入
方法一:
1
2
3>> extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
方法二:
1
2
3extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}命名关键字参数
在函数定义中使用
*后的参数,它们必须在调用时以name=value的形式显式传递。
限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。
示例:
1 | def person(name, age, *, city, job): |
命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
调用方法如下:
1 | person('Jack', 24, city='Beijing', job='Engineer') |
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
1 | person('Jack', 24, 'Beijing', 'Engineer') |
命名关键字参数可以有缺省值,从而简化调用:
参数的顺序
在 Python 中,函数的参数顺序有一个明确的规定,这有助于确保函数调用时参数的正确匹配和解读。函数参数的顺序可以分为以下几种类型:
函数参数的顺序
位置参数(Positional Arguments):
这些参数在函数调用时通过位置传递。它们必须按照在函数定义中声明的顺序提供。
示例:
1
2
3
4def func(a, b, c):
print(a, b, c)
func(1, 2, 3) # a=1, b=2, c=3
默认参数(Default Arguments):
默认参数在函数定义时提供了一个默认值。如果调用时不提供该参数的值,则使用默认值。
默认参数必须在所有非默认参数之后定义。
示例:
1
2
3
4
5
6def func(a, b=2, c=3):
print(a, b, c)
func(1) # a=1, b=2, c=3
func(1, c=4) # a=1, b=2, c=4
func(1, b=5, c=6) # a=1, b=5, c=6
关键字参数(Keyword Arguments):
这些参数在函数调用时通过指定名称来传递,可以改变参数的顺序。
关键字参数必须在所有位置参数之后提供。
示例:
1
2
3
4def func(a, b, c):
print(a, b, c)
func(a=1, c=3, b=2) # a=1, b=2, c=3
可变位置参数(*args):
用于接收任意数量的位置参数,这些参数将被收集到一个元组中。
*args必须在位置参数和默认参数之后定义。示例:
1
2
3
4def func(a, b, *args):
print(a, b, args)
func(1, 2, 3, 4, 5) # a=1, b=2, args=(3, 4, 5)
命名关键字参数(*):
用于定义所有后续的参数必须通过关键字传递。
*后面的参数称为命名关键字参数,调用时必须以name=value的形式指定。示例:
1
2
3
4def func(a, b, *, x=10, y=20):
print(a, b, x, y)
func(1, 2, x=30, y=40) # a=1, b=2, x=30, y=40
可变关键字参数( kwargs)**:
用于接收任意数量的关键字参数,这些参数将被收集到一个字典中。
**kwargs必须在所有位置参数、默认参数、*args和命名关键字参数之后定义。示例:
1
2
3
4def func(a, b, **kwargs):
print(a, b, kwargs)
func(1, 2, x=30, y=40) # a=1, b=2, kwargs={'x': 30, 'y': 40}
总结
- 位置参数:必须按照定义的顺序提供。
- 默认参数:必须在所有位置参数之后定义,并且可以省略。
- 关键字参数:可以在调用时以名称指定参数值,顺序可以不同。
- 可变位置参数 (
*args):用于接收任意数量的位置参数,定义在位置参数和默认参数之后。 - 命名关键字参数 (
*):用于将所有后续的参数设为命名关键字参数。 - 可变关键字参数 (`kwargs`)**:用于接收任意数量的关键字参数,定义在所有其他参数之后。
函数参数的顺序确保了函数定义和调用的一致性和灵活性。
参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数和关键字参数。
匿名函数
lambda 函数的语法只包含一个语句,如下:
1 | lambda [arg1 [,arg2,.....argn]]:expression |
lambda是 Python 的关键字,用于定义 lambda 函数。arguments是参数列表,可以包含零个或多个参数,但必须在冒号(:)前指定。expression是一个表达式,用于计算并返回函数的结果。




