python 函数系列知识

函数的定义

  1. 函数定义不会执行函数的代码, 在内存中保存函数的名字
  2. 函数名需要满足标识符规则, 以数字, 字母和下划线组成, 不能以数字开头,不能和关键字重名
# 定义函数 func()
def func():
	print('人生苦短')
	print("我用python")

函数的调用

  1. 函数调用, 才会执行函数中的代码
  2. 函数必须先定义后使用
  3. 函数调用的时候,才会执行, 会在内存中去找函数名, 找到了就会执行, 没找到就会报错
# 定义函数
def func():
	print('人生苦短')
	print("我用python")


func()

# 控制台输出
人生苦短
我用python

函数的参数

  1. 想让函数更加的通用,在函数外部将数据值传递到函数内使用( 在函数调用的时候, 给他数据值 )
  2. 而这个数据值就是参数, 参数分为形参, 和实参
  3. 形参: 在函数定义时, 括号中的变量, 称为形参, 相当于是具体数据的占位(作用域 : 函数内部)
  4. 实参: 在函数调用的时候, 括号中的数据值, 称为实参, 会将实参的数据值传递给形参 ( 实参的个数必须和形参的个数保持一致, 否则会报错)
# 定义函数
def my_sum(num1, num2):  # num1 和 num2 称为形式参数, 形参, 给实际的数据占位
	"""求 num1 + num2 的和"""
	# 形参的使用范围: 只能在函数内部使用
	num = num1 + num2 
	print(num)


# 函数的调用
my_sum(1, 2)  # 1 和 2 就称为实参, 实参, 将 1 和 2 的值传递给 num1 和 num2
my_sum(100, 200)  # 函数的实参的个数和形参的个数需要保持一致, 如果少实参, 则会报错

局部变量

定义在函数内部的变量, 称为局部变量

  1. 局部变量能否在函数外部使用 —> 不能
  2. 是否可以再其他函数中定义相同名字的局部变量 —> 可以再不同函数内部定义相同名字的局部变量, 两者之间没有影响
  3. 局部变量的作用域: 当前函数内部
  4. 生命周期: 在函数内部定义开始, 到函数结束为止
# 定义一个函数
def func():
	""" num 就是局部变量"""
	num = 100
	print(100)


# 函数调用
func()
# print(num) # 程序报错, 局部变量不能再函数外部使用

# 控制台输出
100

全局变量

定义在函数外部的变量, 称为全局变量

  1. 定义的全局变量,可以在函数内部读取
  2. 定义的全局变量, 不可以自函数内部直接修改
  3. 在函数内部不能直接修改全局变量, 想要在函数内部修改全局变量的值, 需要使用 golbal 声明
# 定义一个全局变量
g_num = 10


# 定义一个函数, 看是否可以读取  ---> 可以
def read_num():
	print("read_num", g_num)


# 函数的调用
read_ num()

# 控制台输出
read_num 10


# 定义函数, 看是否可以修改全局变量的值  ---> 不可以
def write_num():
	#本意是修改全局变量的值, 但实际上实在函数内部定义一个局部变量 g_num
	g_num = 100
	print("write_num", g_num)


# 调用函数
write_num()

# 控制台输出
write_num 100


#定义一个函数, 在函内部修改全局变量的值, 需要使用global声明
def write_num1():
	# 在使用全局变量之前, 使用 global 声明
	global g_num
	g_num = 1000
	print("write_num1", g_num)


# 调用函数
write_num1()
read_ num()  # 判断全局变量是否被修改,之前函数 read_num() 输出的是 read_num 10

# 控制台输出
write_num1 1000
read_num 1000

返回值

  1. 返回值就是函数执行的结果, 会将执行的结果进行返回 ( eg. input() 的返回值是输入的内容, print() 的返回值是 None)
  2. 使用 return 返回 —> return 数据值
  3. 函数内部中定义的局部变量, 或者是函数执行的结果, 需要在函数外部使用.,需要使用 return 将局部变量或者是函数执行的结果, 返回给外部
  4. return 会结束函数的执行, return 之后的代码不会执行
  5. return 只能在函数中使用
# 定义一个函数
def my_sum(num1, num2):
	# 函数默认返回的是 None
	num = num1 + num2
	# 可以使用 return 将程序中的数据但会
	return num  # return 会结束函数的执行, return 之后的代码不会被执行


result = my_sum(10, 20)
print(my_sum(10, 20))

# 在函数外部需要将求和的结果和字符串连接
print('求和的结果是%d' % result)

# 控制台输出
30
求和的结果是30

函数的嵌套

def test_b():
	print('--- testb start ---')
	print('这里是函数 testb 执行的代码')
	print('--- testb end ---')


def test_a():
	print('--- testa start ---')
	test_b()
	print('--- test end ---')


test_a()

# 执行的结果
--- testa start ---
--- testb start ---
这里是函数 testb 执行的代码
--- testb end ---
--- testa end ---
def my_sum(a, b, c):
	"""对3个数求和"""
	num = a + b + c
	return num


def average3number(a, b, c):
	# 先求和
	num = my_sum(a, b, c)
	# 求平均数
	avg = num / 3
	return avg

num1 = my_sum(10, 20, 30)
print(num1)
num2 = average3number(10, 20, 30)
print(num2)

# 控制台输出
60
20.0

函数嵌套应用举例

def print_line1(char, num):
	"""打印一行字符"""
	print(char * num)

def print_line(line, char, num):
	"""打印多行"""
	for i in range(line):
		print_line1(char, num)


print_line(5, *, 20)

# 控制台输出
********************
********************
********************
********************
********************

函数的传参方式

  1. 位置传参(位置实参): 普通的传参方式,直写数据值
  2. 按照形参的顺序获取实参的值
  3. 关键字传参(关键字实参) : 指定将数据 (实参) 给哪个形参, 关键字必须要存在
  4. 混合使用需要注意(1, 换剪子实参要放在位置实参的后边. 2, 不能对一个形参给多个值)
def func(a, b, c)
	print(f'a: {a}, b: {b}, c: {c}')


# 位置传参
func(1, 2, 3)


# 关键字传参 关键字实参必须是存在的形参
func(c=1, b=2, a=3)
# func(cc=1, b=2, a=3)  # 程序报错, cc 不是形参值


# 位置传参和关键字传参混合使用
func(20, 30, c=10)
# func(c=10, 20, 30)  # 程序报错, 位置实参必须在关键字实参之前
# func(10, 20, b=30)  # 程序报错, 形参 b 多获得了多个值

# 控制台输出
a: 1, b : 2, c : 3
a: 3, b : 2, c : 1
a: 20, b : 30, c : 10

缺省参数

缺省参数: 在函数定义的时候, 给形参一个数据值, 那这个形参就称为缺省参数

  1. 函数调用的时候, 如果给缺省形参传递实参值, 使用传递的数据值
  2. 如果不给缺省形参传递数据值, 使用的默认值

不定长参数

  1. 不定长参数(形参): 参数的个数是不确定的, 可以接收多个
  2. 不定长位置参数(不定长元组参数): 可以接收所有的位置实参
  3. 不定长关键字参数(不定长字典参数): 可以接收所有的关键字实参
# 不定长元组形参(写在普通形参的后边)
def my_sum(*args):  # 使用 * 标记, 使 args 变为不定长元组形参
	"""求和函数"""
	print(args)
	num = 0
	for i in args:
		num += 1
	# 使用 return 将求和结果返回
	return num


print(my_sum(10, 20))
print(my_sum(10, 20, 30))


# 不定长字典参数
def show_info(**kwargs):  # 需要使用 ** 做标记, kwarg 就是一个字典, 变成字典参数
	"""
	打印信息
	:param name
    :param age
    :param height
    :param weight
	"""
	print(kwargs)
	name = kwargs.get('name', '未填写')
	age = kwargs.get('name', '未填写')
	height = kwargs.get('height', '未填写')
	weight = kwargs.get('weight', '未填写')
	print(name, age, height, weight)
	pass


show_info(name='qym')
show_info(name='小王')
show_info(name='小王', age=18)

# 控制台输出
(10, 20)
30
(10, 20, 30)
60
{'name': 'isaac'}
isaac 未填写 未填写 未填写
{'name': '小王'}
小王 未填写 未填写 未填写
{'name': '小王', 'age': 18}
小王 18 未填写 未填写

完整的形参顺序

完整的形参顺序: 普通,不定长元祖形参, 缺省参数, 不定长字典形参

  1. 不能将缺省参数放在 * args (不定长元祖参数)前边 —> 不能这样定义SyntaxError: positional argument follows keyword argument 位置的实参放在了关键字后边
def show_info(name, *args, age=18, **kwargs)
	print('name', name)
	print('args', args)
	print('age', age)
	print('kwargs', kwargs)
	pass


show_info('qym', 1, 2, 3, age=20, a=10, b=20)
print('-' * 20)
show_info('qym', 1, 2, 3, 4, a=10, b=20)
print('-' * 20)
a = [1, 2, 3]
b = {'a': 10, 'b': 20}
show_info('qym', *a, **b)

# 控制台输出
name qym
args (1, 2, 3)
age 20
kwargs {'a': 10, 'b': 20}
---------------------------
name qym
args (1, 2, 3, 4)
age 18
kwargs {'a': 10, 'b': 20}
---------------------------
name qym
args (1, 2, 3)
age 18
kwargs {'a': 10, 'b': 20}
	

引用

  1. id(变量) 可以查看变量中存储的引用值
  2. 引用是对内存地址的封装, 引用值一样, 代表着内存也是一样的
  3. 使用赋值运算符= , 会改变引用值
  4. 变量1 = 变量2 (将变量 2 的引用给到变量1, 变量1 和变量 2 的引用值是一样的, 指向同一块内存)
  5. 变量3 = 数据 (开辟新的内存空间, 会将数据的地址给到变量3)
  6. 字符串和整数, 会有一个优化(优化内存,如果值相等的话,会使用同一个地址)

可变和不可变类型

可变和不可变类型: 在不改变变量引用的前提下, 能否直接修改变量中的内容

  1. 能修改则为可变类型: 字典 dict 列表 list 集合 set
  2. 不能修改则为不可变类型: 整数 int 小数 float 字符串 str 元组 tuple
# 可变类型 list
my_list = [1, 2]
print(id(my_list1))

my_list.append(3)  # 没有修改变量 my_list 的引用
print(my_list1)
print(id(my_list1))

my_list1[0] = 100  # 没有修改变量 my_list 的引用
print(id(my_list1))

my_list1 = [1]
print(my_list1)
print(id(my_list1))
print('*' * 30)

# 不可变类型 int
num = 1
print(id(num))
num = 2
print(id(num))
print('-' * 30)

# 不可变类型 字符串
my_str = 'hello world'
print(id(my_str))

my_str1 = my_str.replace('1', 'L')
print(id(my_list))
print(id(my_list1))
print('*' * 30)

# 不可变类型 元组
my_tuple = (1, 2, [3, 4])
print(id(my_tuple))
my_tuple[2][0] = 10  # 没有修改变量 my_tuple 的引用
print(my_tuple)
print(id(my_tuple))

# my_tuple[1] = 12  # 程序出错, 不能修改元组中的数据
# print(my_tuple)
# print(id(my_tuple))

# 控制台输出
2612553783304
[1, 2, 3]
2612553783304
2612553783304
[1]
2612553783496
******************************
1945487024
1945487056
------------------------------
2612553782512
2612553782512
2612553784944
******************************
2612553714784
(1, 2, [10, 4])
2612553714784

组包和拆包

组包(pack) : 把等号 = 右边多个数据包装成元组
拆包(unpack) : 等号左边的变量来接收等号右边的多个数据值[ 变量的个数和数据元素的个数要相等]

# 组包 把等号右边多个数据包装成元组
num = 1, 2, 3
print(num, type(num))

"""
拆包: 等号左边的变量和接受等号右边的多个数据值
变量的个数和数据元素的个数要相等
"""
a, b, c = 10, 20, 30
print(f'a: {a}, b: {b}, c: {c}')

# 应用1. 交换两个变量的值
a = 100
b = 200
a, b = b, a

print(a, b)


print('-' * 30)
# 应用2. 函数返回多个值, 组包
def func()
	return 1, 2, 3  # 组包


num1 = func()
print(num1)

a, b, c = func()
print(f'a: {a}, b: {b}, c: {c}')

# 应用3. 字典遍历键值对的时候
my_dict = {'a': 100, ; 'b': 200, 'c': 300}
for key, value in my_dict:
	print(key, value)


# 控制台输出
(1, 2, 3) <class 'tuple'>
a: 10,b: 20,c: 30
200 100
------------------------------
(1, 2, 3)
a: 1,b: 2,c: 3
a 100
b 200
c 300
发布了56 篇原创文章 · 获赞 17 · 访问量 2167

猜你喜欢

转载自blog.csdn.net/LanlanDeming/article/details/103378511