函数及其参数的使用
函数及其参数的使用
一 函数的基本使用
1 什么是函数
函数就是具备某一功能的工具。
2 为什么要有函数
### 1.对于内置函数来说,主要是为了:
(1) 提升开发效率。
### 2.对于自定义函数来说:
(1) 为了增强程序的组织结构性、提升可读性;
(2) 减少代码冗余;
(3) 提升程序的可维护性与扩展性。
### PS:自定义函数是把程序中实现某一功能的代码组织整理到一起。
3 如何用函数
3.1 使用的原则:
先定义,后调用。
3.2 定义/调用函数的基本语法:
# 定义函数:
def func(参数1,参数2,···):
'''文档注释'''
code1
code2
code3
···
return 返回值
# 调用函数,函数名加括号
func(参数1,参数2,···)
3.3 定义函数的本质:
定义函数就是申请内存空间把函数替代码保存下来,然后把内存地址绑定给函数名——》函数名=函数的内存地址。
def sayhello():
print("=" * 10)
print('hello')
print("=" * 10)
print(sayhello) # <function sayhello at 0x0000012A35F15F70>
3.4 调用函数的本质:
函数名+括号——》函数的内存地址+(),会触发函数体代码的运行。
sayhello() # ==========
# hello
# ==========
4 定义函数的三种格式
# 无参函数/有参函数/空函数
### 4.1 无参函数
即定义了一个不需要传参数的函数。
def login():
inp_name = input('your name:').strip()
inp_pwd = input('your pwd:').strip()
if inp_name == 'zhangsan' and inp_name == '123':
print('login successful')
else:
print('login error')
login()
### 4.2 有参函数
即定义了一个需要传参数的函数。
def max2(x, y):
if x > y:
print(x)
else:
print(y)
max2(11,22) # 22
### 4.3 空函数
顾名思义,即定义了一个实际没有函数体代码的函数,一般用于开发中的功能占位,后续会补全功能。
def func():
pass # 使用···也可以
5 函数的返回值
5.1 return是什么
函数体代码结束的标志是return,而且调用函数一定会有返回值。函数内可以有多个return,但只要执行一次,函数就会立即结束,并会把return后的值当作本次调用的结果返回。
5.2 函数返回值的三种形式
#### (1) return 值:
返回的就是该值本身。
def func():
return 123
res = func()
print(res) # 123
#### (2) return 值1,值2,值3:
返回值为多个时,会返回一个元组。
def func():
return 123, "abc", 3.1
res = func()
print(res) # (123, 'abc', 3.1)
#### (3) 没有return:
默认返回None。
def func():
# return None 属于多此一举,本身就默认了返回None
pass
res = func()
print(res) # None
6 函数调用的三种形式:
def max2(p1_msalary, p2_msalary):
if p1_msalary > p2_msalary:
return p1_msalary
else:
return p2_msalary
x = max2(10, 11)
print(x * 12)
6.1 语句形式:单纯的调用函数
print("hello world") # 调用内置函数print
max2(10,11)
6.2 表达式形式:作为表达式的一部分
x = max2(1, 2)
res = max2(1, 2) * 12
print(res)
6.3 可以把函数的调用当作值传给另一个函数:
print(max2(1, 2))
res = max2(max2(10, 11), 12)
print(res)
7 总结:函数使用的两个阶段
函数的使用一定要分两个阶段去看:
1.定义阶段:只检测语法,不执行代码;如果发生语法错误,会立即被检测出来。
def func():
print("hello" # SyntaxError: unexpected EOF while parsing
2.调用阶段:执行函数体代码;如果发生的错误不是语法错误,而是逻辑错误,只能在调用阶段检测到。
def func():
xxx
func() # NameError: name 'xxx' is not defined
二 函数的参数
1 函数参数的两大分类
#### 1.1 形参:
在定义函数时,括号内定义的变量名,称之为形式参数,简称形参==》相当于变量名,用于接收外部传来的值。
def func(x, y):
x = 1
y = 2
print(x) # NameError: name 'x' is not defined
print(y) # NameError: name 'y' is not defined
#### 1.2 实参:
在调用阶段,括号内传入的值,称之为实际参数,简称实参==》变量值,用于为形参赋值用。
func(1, 2)
#### 1.3 总结:
在函数调用时,会将实参的值绑定给形参,这种绑定关系只能在函数内使用,在函数调用完毕后,实参会与形参接触绑定,回收占用的内存空间。
2 在python中参数的种类
2.1 位置参数
2.1.1 位置形参,定义及特点:
##### ①定义:
在函数定义阶段按照从左到右的顺序依次定义形参(变量名) ,称之为位置形参。
##### ②特点:
必须被传值,不能多,也不能少。
def func(x, y):
print(x, y)
func(1, 2) # 1 2
func(1) # TypeError: func() missing 1 required positional argument: 'y'
2.1.2 位置实参,定义及特点:
##### ①定义:
在函数的调用阶段,按照从左到右的顺序依次定义实参(传入的变量值) ,称之为位置实参。
##### ②特点:
按照位置传值,一一与形参对应。
def func(x, y):
print(x, y)
func(1, 2) # 1 2
func(2, 1) # 2 1
2.2 关键字实参,定义、特点及混用:
#### (1) 定义:
在函数调用阶段按照key = value 的形式为指定的形参名传值,该形式称之为关键字实参。
#### (2) 特点:
在传值时可以完全打乱顺序,但是仍然能够指名道姓的为指定的形参传值。
def func(x, y):
print(x, y)
func(1, 2) # 1 2
func(y=2, x=1) # 1 2
2.2.1 注意:混用位置实参与关键字实参时
①位置实参必须放在关键字实参前面;
def func(x, y):
print(x, y)
func(1, 2, x=111) # TypeError: func() got multiple values for argument 'x'
②不能为同一个形参重复赋值。
def func(x, y):
print(x, y)
# func(1, y=2) # 1 2 操作正确,无问题
func(y=2, 1) # SyntaxError: positional argument follows keyword argument
2.3 默认形参,定义及特点:
#### (1) 定义:
在函数定义阶段就已为某个形参赋值,该形参称之为有默认值的形参,简称默认形参。
#### (2) 特点:
定义阶段就已经被赋值,意味着在函数的调用阶段可以不用为其赋值。
def func(x, y=1111):
print(x, y)
func(1) # 1 1111
func(1,2222) # 1 2222
2.3.1 注意:3个注意事项
①默认形参应该放在位置形参后面;
def func(y=1, x):
print(x, y)
func(2) # SyntaxError: non-default argument follows default argument
②默认形参的值通常是不可变类型;因为函数的调用应该做到彼此之间没有关联。
def func(name, names=[]):
names.append(name)
print(names)
func("name1") # ['name1']
func("name2") # ['name1', 'name2']
func("name3") # ['name1', 'name2', 'name3']
解决办法:
def func(name, names=None):
if names == None:
names = []
names.append(name)
print(names)
func("name1") # ['name1']
func("name2") # ['name2']
func("name3") # ['name3']
③默认形参的值只在函数定义阶段被赋值一次,函数定义之后的改变对形参没有影响。
m = 333
def func(x, y=m): # y=333
print(x, y)
m = 44444
func(1) # 1 333
三 *与**在形参中的使用
1 可变长参数
可变长参数指的是参数的个数不固定。
站在实参的角度,实参是用来为形参赋值的,如果实参的个数不固定,那么必须有对应的形参能够接受溢出的实参。
1.1 在形参中使用*与**
#### (1) 在形参名前加*:
*会把溢出的位置实参汇总存成元组,然后赋值给其后的形参名。
# 代码示例:
def add(*nums):
res = 0
# print(nums) # (1, 2, 3)
for num in nums:
res += num
return res
res = add(1,2,3)
print(res) # 6
===========分割线============
def add(*nums):
res = ''
print(nums) # ('你', '好', '啊')
for num in nums:
res += num
return res
res = add('你','好','啊')
print(res) # 你好啊
#### (2) 在形参名前加**:
**会把溢出的关键字实参汇总存成字典,然后赋值给其后的形参名。
# 代码示例:
def func(x, **y):
print(x)
print(y)
func(1, a=111, b=222, c=333) # 1
# {'a': 111, 'b': 222, 'c': 333}
func(a=111, b=222, x=1, c=333) # 1
# {'a': 111, 'b': 222, 'c': 333}
1.2 在实参中用*与**:
#### (1) 在实参名前加*
*会把其后的值分解成位置实参。
# 代码示例:
def func(x, y, z):
print(x, y, z)
nums = [1, 2, 3]
func(*nums) # 1 2 3 ;相当于func(1,2,3)
str1 = '你好啊'
func(*str1) # 你 好 啊
#### (2) 在实参名前加**:
**会把其后的值分解成关键字实参。
# 代码示例:
def func(x, y, z):
print(x, y, z)
dic = {'y':111, 'z':222, 'x':333}
func(*dic) # y z x
func(**dic) # 333 111 222 ; func(y=111,z=222,x=333)
1.3 在形参与实参中混用*与**
def index(x, y, z, a, b, c):
print('index===>', x, y, z, a, b, c)
def wrapper(*args, **kwargs): # args=(1, 2, 3,) kwargs={"a":111,"b":222,"c":333}
index(*args, **kwargs) # index(*(1, 2, 3,),**{"a":111,"b":222,"c":333})
# # index(1,2,3,c=333,b=222,a=111)
wrapper(1, 2, 3, a=111, b=222, c=333) # index===> 1 2 3 111 222 333
2 命名关键字参数以及参数组合使用顺序(了解)
#### 1.命名关键字参数:
在*与**之间的参数,无论是什么形式(key=value 或 只有参数名) ,都是命名关键字参数,如果没有事先被赋值,那么必须被传值。
# 示例一:
def func(*args, y, **kwargs):
print(args)
print(y)
print(kwargs)
# func(1,2,3,a=1,b=2,c=3) # 报错,不可以这样传值,必须给y赋值
func(1,2,y=3,a=1,b=2,c=3) # 正确传值方式
# (1, 2)
# 3
# {'a': 1, 'b': 2, 'c': 3}
# 示例二:
def func(*args, x=1, y, **kwargs):
print(args)
print(x, y)
print(kwargs)
func(1, 2, y=3) # (1, 2)
# 1 3
# {}
func(1, 2, x=111, y=3) # (1, 2)
# 111 3
# {}
#### 2.参数的组合使用顺序
位置参数,默认参数,可变长度参数,命名关键字参数,可变长度参数
def func(x, y=111, *args, z, **kwargs):
pass
3 函数参数的总结
形参中带*与**是汇总操作;
实参中带*与**是分解操作。

浙公网安备 33010602011771号