python笔记-函数

课程导入

有一天,你有一个需求:统计两个班级的《python程序》课程成绩,计算各自的最高分、总分。

在你学习函数之前,你很可能这么写:

class1 = [77, 88, 100, 66, 45, 65, 32, 78, 89, 90, 94, 90]
class2 = [45, 67, 89, 87, 63, 79, 97, 90, 91, 43, 69, 23, 80, 99]

# 统计1班最高分、总分
max1 = 0
sum1 = 0
for one in class1:
	if one > max1:
		max1 = one
	sum1 += one
print("1班最高分:", max1, "总分:", sum1)

# 统计2班最高分、总分
max2 = 0
sum2 = 0
for two in class2:
	if two > max2:
		max2 = two
	sum2 += two
print("2班最高分:", max2, "总分:", sum2)

然后你会发现,你的重复代码几乎占了50%,如果要统计n个班级,这里的重复代码就要写n遍。

所以,可不可以把一个程序中重复率高的代码写成一种公共的样式,用的时候“套公式”呢?当然可以,

这就是——函数。

上述代码可改写如下(这段代码并不优美,但是是初学阶段最容易理解的写法):

def tj(listData):
	m = 0
	s = 0
	for i in listData:
		if i > m:
			m = i
		s += i
	print("最高分:", m, "总分:", s)

class1 = [77, 88, 100, 66, 45, 65, 32, 78, 89, 90, 94, 90]
class2 = [45, 67, 89, 87, 63, 79, 97, 90, 91, 43, 69, 23, 80, 99]

print("1班", end="");tj(class1)
print("2班", end="");tj(class2)

函数概念

函数:把一个程序中重复率高的代码写成一种公共的、可重复调用的样式,此样式即为函数,使用def关键字声明。格式如下:

def 函数名称(参数):
	# 代码
	# return 值,这个返回值可能有,也可能没有

辅助理解:我要吃蛋糕,我需要给蛋糕店(函数)提供一些信息,比如我需要多大的蛋糕、放哪些水果(参数),然后蛋糕店(函数)给我它处理完成的结果(蛋糕),这个蛋糕,就是返回值。至于这个过程中蛋糕是怎么做出来的,我不需要知道,蛋糕店(函数)知道即可。

示例:比较数字、字符串:

def max(a, b):
	return a if a > b else b

print("比较数字:", max(1, 88))
print("比较字符串:", max("zyx", "abcd"))

说明文档

程序员代码规范中,需要给自定义的函数写一个总注释,用来解释这个函数的功能。

其他程序员在调用这个函数时,可以通过help(函数名称)或函数名称.__doc__的方式获取该注释。

def max(a, b):
	'''
	这个函数可以比较数字大小、字符串长度,返回最大或最长的数据
	'''
	# 我是一般的注释
	return a if a > b else b

help(max)
print("**********")
print(max.__doc__)

结果:

Help on function max in module __main__:

max(a, b)
    这个函数可以比较数字大小、字符串长度,返回最大或最长的数据

**********

	这个函数可以比较数字大小、字符串长度,返回最大或最长的数据
	
[Finished in 61ms]

参数详解

形参&实参

函数的参数,有形式参数(形参)和实际参数(实参)之分。这说法考试常见,但实际工作中直接说“参数”更多。

  • 形参:函数声明的时候的参数,跟def出现在一起,是一个数据名字
  • 实参:函数使用的时候的参数,是传给函数的具体数据
def add(a, b): # a, b为形参
	return a + b

print(add(10, 11)) # 实参
print(add("hello", "world")) # 实参

值传递&引用传递

  • 值传递:传给函数的是数值,即不可变数据类型:数字、字符串、元组
  • 引用传递:传给函数的是地址,即可变数据类型:列表、字典

例1:值传递传给函数的是变量的值,这个值在函数内部做的任何操作,都不会影响原始变量。

def change(a, b):
	a = 0
	b = 'xyz'

a = 10; b = 'abc'
change(a, b)

print(a, b) # 10 abc

例2:引用传递传给函数的是地址,如果对这个地址上的数据进行了修改,那么对于所有引用这个地址的变量,相应位置的值都会改变。

def change(a, b):
	a[0] = 0
	b[1] = 'x'

a = [10, 11, 12]; b = {1:'a', 2:'b'}
change(a, b)

print(a, b) # [0, 11, 12] {1: 'x', 2: 'b'}

位置参数(必备参数)

是参数个数在声明时就固定了的一种参数类型(本篇上述函数全部都是)特点:

  1. 形参和实参数量必须一致
  2. 形参和实参位置必须一致,数据类型1:1对应的上才行

关键字参数

使用形参名字来声明哪一个实参是自己,因此不需要保证形参和实参位置一致:

def change(a, b, c):
	print(a, b, c)

# 位置参数
change(10, 'abc', (99,)) # 10 abc (99,)

# 关键字参数 认识一下
change(a=10, b='abc', c=(99,)) # 10 abc (99,)
change(b=10, a='abc', c=(99,)) # abc 10 (99,)

# 关键字参数 搞事情写法
# change(a=10, b='abc', (99,)) #SyntaxError: positional argument follows keyword argument
change(10, b='abc', c=(99,)) # 10 abc (99,)
change(10, c='abc', b=(99,)) # 10 (99,) abc
# change(10, 'abc', b=(99,)) #TypeError: change() got multiple values for argument 'b'

SyntaxError原因:位置参数必须在关键字参数前面。

TypeError原因:b参数在末尾声明,于是默认b前面的10, ‘abc’, 都是a的值,继而报错。

默认值参数

形参在声明的时候,可以给定默认值。如果使用该函数的时候实参也给了值,会覆盖默认值,如果没给,那么函数内部根据默认值执行。

def change(a, b, c=100):
	print(a, b, c)

change(10, 11) # 10 11 100
change(10, 11, 12) # 10 11 12

# 又来搞事情
change(a=10, b=11) # 10 11 100
# change(a=10) # TypeError: change() missing 1 required positional argument: 'b'

⚠️:带有默认值参数的函数,在声明的时候必须把默认值放在参数最后面,否则:

def change(a, b=100, c): # SyntaxError: non-default argument follows default argument

获取函数默认值

可以使用“函数名.defaults”查看函数的默认值参数的当前值,其返回值是一个元组。

def change(a, b=2, c=3):
	a = 10; b = 20; c = 30
	print("函数内部:change.__defaults__ =", change.__defaults__)
change(100, 200, 300)
print("函数外部:change.__defaults__ =", change.__defaults__)

结果,两个输出都是 (2, 3)

可变参数

有时候,参数个数我们自己都不知道,可能传2个,也可能传3个,你可以这样写(用的少,暂时写这么多,认识即可):

可变位置参数*args

def sum_numbers(*args):
    sum = 0
    for num in args:
        sum += num
    return sum
print(sum_numbers(1, 2, 3)) # 6

可变关键字参数**kwargs

def configure(a, b, **kwargs):
    print(f"a: {a}, b: {b}")
    for key, value in kwargs.items():
        print(f"可变关键字参数:{key}: {value}")
configure("www.baidu.com", b=8080, use_ssl=True)
print()
configure("admin", b=123, name="Alice", age=30, job="Engineer")

结果:

a: www.baidu.com, b: 8080
可变关键字参数:use_ssl: True

a: admin, b: 123
可变关键字参数:name: Alice
可变关键字参数:age: 30
可变关键字参数:job: Engineer
[Finished in 42ms]

返回值

  • python函数有一个特殊的常量 None(N 必须大写)。它不表示 0,也不表示空字符串,而表示没有值,也就是空值。
  • 所有看似没有return的函数,python都会在解析时在其末尾加上return None,也就是说,没有声明返回值的函数,默认返回值都是None。
  • 同一个函数中,如果出现分支(if、elif、else),可能会有多行return代码,但只要有一个return被执行,函数的执行就会全部结束。
def max1(a, b):
	return a if a > b else b
def max2(a, b):
	print(a if a > b else b)

print("max1返回值:", max1(1, 4))
print("max2返回值:", max2(1, 4))

结果:

max1返回值: 4
4
max2返回值: None

多个返回值

可按元组、字典return多个值:

# example1返回两数中最大值,example2返回元组,example3返回字典
def example1(a, b):
	return a if a > b else b
def example2(a, b):
	return a, b
def example3(a, b):
	return {'a': a, 'b': b}

print(example1(1, 4)) # 4

x, y = example2(1, 4)
print(x, y) # 1 4
print(type(example2(1, 4))) # <class 'tuple'>

z = example3(1, 4)
print(z['a'], z['b']) # 1 4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值