Python学习笔记(2)

函数

函数的特点

  • 功能性:一个函数要有明确的功能
  • 隐藏细节:调用者不需要关注函数的细节
  • 函数的目的:减少重复代码

Python 中函数的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def funcname(parameter_list):
pass

# 与Python内置的max函数重名了,会覆盖内置的max函数
def max(a, b):
if a > b:
return a
else:
return b


print(max(1, 2))


def func():
print('hello world')


print(func()) # None,无返回值则默认返回None
  • 参数列表可有可无
  • 函数内可以return value,如果没有 return,则默认返回 None
  • 函数必须先定义才能使用
  • 函数名不能与 Python 内置的函数名重名,否则会覆盖内置函数

Python 中关于递归函数:

  • Python 默认的递归次数是有限的
  • 可以通过sys.setrecursionlimit(10000)方法来修改递归次数

关于 print 函数:

1
2
a = b = c = 1
print(a, b, c) # 分别打印a, b, c

Python 中函数可以返回多个值

1
2
3
4
5
6
7
8
9
def func(num):
a = num * 2
b = num * 3
return a, b

ret = func(10) # ret是一个元组
print(ret)
a, b = func(10) # 推荐的做法,序列解包,不要使用元组[序号]
print(a, b)

Python 中的序列解包和链式赋值

1
2
3
4
a, b, c = 1, 2, 3
d = 1, 2, 3 # a是一个元组
a, b, c = d # 序列解包
a = b = c = 1 # 链式赋值

必须参数和关键字参数

  • 必须参数:函数参数列表中定义的,必须传递的参数,如果不传则会编译错误
  • 关键字参数:明确指定参数的值,可以无视参数的顺序
  • 如果参数列表中既有必须参数,又有关键字参数,则关键字参数必须位于必须参数之后
1
2
3
4
5
6
7
8
9
10
11
12
def add(num1, num2):
return num1 + num2


ret = add(12, 13) # 以必须参数的形式调用
print(ret)
ret1 = add(num2=13, num1=14) # 以关键字参数的形式调用
print(ret1)
ret2 = add(14, num2=15) # Ok, 关键字参数可以在必须参数之后
print(ret2)
ret3 = add(num1=14, 15) # error,关键字参数不能在必须参数前
print(ret3)

默认参数

  • 默认参数必须位于参数列表的最后
  • 默认参数既可以使用关键字参数,也可以使用必须参数,也可以不传
1
2
3
4
5
6
7
8
9
10
11
12
def add(num1, num2, num3=3, num4=4):
return num1 + num2 + num3 + num4


print(add(10, 20, 30, 40))
print(add(10, 20, num4=40, num3=30))
print(add(10, 20, num4=40))
print(add(10, 20, num3=30))
print(add(10, 20, 30))
print(add(10, 20))
print(add(num1=10, num2=20))
print(add(num2=20, num1=10))

可变参数

  • 可变参数,给参数名前加一个星号*
  • 传递参数是,可以传一个元组或列表,前面要加一个星号*
  • 可变参数之后可以有关键字参数,但不能有必须参数,必须参数必须位于可变参数之前,默认参数也要使用关键字参数的形式进行调用
  • 可以参数也可以什么都不传,相当于传一个空的元组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def fun(*param):
print(param)


fun(1, 2, 3, 4)
a = (1, 2, 3, 4)
fun(*a) # *相当于展开元组内的元素
b = [1, 2, 3, 4]
fun(*b) # 同上


def fun1(num1, *param):
print(param)
print(num1)

fun1(1, 2, 3, 4) # (2, 3, 4), 1

# 可变参数后有关键字参数
def fun1(num1, *param, num2, num3=3):
print(param)
print(num1)
print(num2)
print(num3)


fun1(1, 2, 3, 4, num2=13) # 1, (2, 3, 4), 13, 3
fun1(1, 2, 3, 4, num2=13, num3=14) # 1, (2, 3, 4), 13, 14
fun1(1, num2 = 13, num3 = 14) # 1, (), 13, 14 可变参数为空元组

关键字可变参数

  • 参数前加两个星号**
  • 传递参数时需要传一个字典或使用关键字参数进行调用
  • 可以参数也可以什么都不传,相当于传一个空的字典
  • 关键字可变参数必须位于参数列表的最后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def fun(**param):
print(param) # param是一个字典
for key, value in param.items():
print('key:' + key + ', value: ' + str(value))


fun(num1=1, num2=2, num3=3)
a = {'aa': 1, 'bb': 2}
fun(**a) # 相当于解包a
fun() # {} , 可变参数也可以什么都不传,相当于传一个空字典

def fun(num1, **param):
print(param) # param是一个字典
print(num1)


a = {'a': 1, 'b': 2}
fun(1, **a)

变量的作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
c = 50 # 全局变量


def add(a, b):
c = a + b # c 相当于一个新的局部变量,覆盖了外部的变量
print(c)


add(1, 2) # 3
print(c) # 50

for i in range(0, 9):
a = 12
print(i)
print(a) # 循环外部可以引用循环内部的变量,Python没有块级作用域

global 关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def fun():
global a # 将a提升为全局作用域,a可以通过import导入其他模块
a = 2

fun()
print(a) # 2

b = 12 # 全局作用域
def fun1(num):
global b
b = b + num # 修改全局作用域的变量b

fun1(11)
print(b) # 23