1.6 函数设计
函数的概念
函数可以用来定义可重用代码、组织和简化代码
# 计算1~10的和
sum = 0
for i in range(1, 11):
sum += i
print(sum)
# 计算2~22的和
sum = 0
for i in range(2, 23):
sum += i
print(sum)
# 计算9~101的和
sum = 0
for i in range(9, 102):
sum += i
print(sum)
# 封装
def getSum(a, b):
result = 0
for i in range(a, b + 1):
result += i
return result
sum = getSum(1,10)
print(sum)
sum = getSum(2,22)
print(sum)
sum = getSum(9,101)
print(sum)
函数是为实现一个操作而集合在一起的语句集
函数有什么好处:
函数的使用可以重用代码,省去重复性代码的编写,提高代码的重复利用率
函数能封装内部实现,保护内部数据,实现对用户的透明
函数使得程序变得模块化,分工明确,利于阅读、调试和修改。函数的定义
函数的组成部分主要有:函数名称,参数,函数体和返回值
def 函数名称(参数):
函数体
return 返回值
参数被称为形式参数或者叫形参,当外界调用函数时,将会传一些数据,这些数据就会被形参所接收。被传进来的数据叫做实际参数或实参。参数是可选的。
num1 = 30;
num2 = 40;
sum = getSum(num1,num2)
print(sum)
某些函数有返回值,而有一些函数没有返回值的。没有返回值就没有return吗?如果没有返回值,return就被隐藏了。
def getSumPrint(a,b):
result = 0
for i in range(a, b + 1):
result += i
print(result)
# return
getSumPrint(10,20)
函数体包含一个定义函数做什么的语句集。
return仅仅表示函数运行结束,一旦函数执行过程遇到return语句,那么函数之后所有的代码都被忽略,直接跳出函数体,函数立即结束,哪怕在一个循环中。并且函数没有返回值的话默认返回None;如果有返回值的话,写在return之后即可,结束函数并将结果返回个调用者。
def func01(a):
if a == 10:
print("哈哈")
return
print("嘻嘻")
return
func01(11)
res = func01(10)
print(type(res))
def func02(a):
for i in range(1,11):
if i == a:
print(i)
# break 跳出循环 接着向下运行
return # 直接结束函数
print(i)
print("啦啦")
return
func02(11)
func02(4)
return都可以返回什么?
什么都不返回:return
任意数据类型:return 'hello'
一个表达式:return 1 + 2
一个判断语句:return 3 > 2
一个变量:return a
一个函数的调用:return func()
多个返回值,以逗号分隔:return a,1+2,'hello'
甚至返回自己:return self
函数可以return几乎所有的Python数据对象。
参数的传递
函数通常都有参数,用于将外部的实际数据传入函数内部进行处理。但是,在处理不同数据类型的参数时,会发生以下两种情况:
Python的函数传递参数时,传递的是实际对象的内存地址
Python的数据类型,主要分为可变对象,不可变对象def func(a): # 局部变量
print("函数内部没有修改前",id(a)) # 520
a = 2
print("函数内部修改后",id(a)) # 536
print("函数内部修改后a=",a) # 2
return
a = 1 # 全局变量
print("调用函数之前",id(a)) # 520
func(a)
print("调用函数之后",id(a)) # 520
print(a)
def test(lst) :
lst.append(4)
print(id(lst))
print(lst)
lst = [1,2,3] # 列表
print(id(lst))
test(lst)
print(id(lst))
print(lst)
关于参数的传递,由于Python是动态语言,变量没有数据类型区分,所以函数是不会检测实参的数据类型,但会是检测个数;数据类型的检测只有在函数内部运行时才会被检测出来。
def add(a, b):
return a + b
add(1, 2)
add(1, 2, 3)
Traceback (most recent call last):
File "C:/Users/HENG/Desktop/PythonCode/Day04/FunctionTest05.py", line 5, in
add(1, 2, 3)
TypeError: add() takes 2 positional arguments but 3 were given
add(1, "hello")
Traceback (most recent call last):
File "C:/Users/HENG/Desktop/PythonCode/Day04/FunctionTest05.py", line 6, in
add(1, "hello")
File "C:/Users/HENG/Desktop/PythonCode/Day04/FunctionTest05.py", line 2, in add
return a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
函数的运行机制
栈是一种先进后出的容器。
函数是基于栈运行的。每次调用一个函数时,系统会自动创建一个关于该函数的内存空间,也称为栈帧,存的它的参数和变量以及执行语句,然后将该栈帧进栈开始运行。当一个函数调用另一个新的函数时,接着系统创建一个新的栈帧,将该栈帧进栈开始运行,那么第一个函数就暂停,直到其上的所有函数执行完毕后,第一个函数接着继续执行。
def multi(a, b, c):
return a ** 2, b ** 2, c ** 2
def add(a, b, c):
return a + b + c
def out(s):
print(s)
def test(a, b):
num1, num2, num3 = multi(a, b, a + b)
out('hello')
return add(num1, num2, num3)
num = test(2, 3)
print(num)
变量的作用域
在函数内部定义的变量称之为局部变量。局部变量只能在函数内部访问。局部变量的作用域所在函数进栈开始执行,直到该函数结束出栈。
同样可以定义全局变量,在所有函数之外定义,可以被所有的函数访问。
示例1:
globalVar = 1
num1 = 3
num2 = 10
def f1():
localVar = 2 # 局部变量 在该函数内创建
print(globalVar) # 全局变量
print(localVar) # 局部变量
print(num1 + 3) # num1 全局变量
num2 = 20 # 局部变量 在该函数内创建
print(num2)
# 如果直接将全局变量,参与运算,直接打印 调用的就是全局变量
# 如果是对全局变量进行修改,则为创建一个同名的局部变量
f1()
print(globalVar)
print(num2)
# NameError: name 'localVar' is not defined
# print(localVar)
示例2:
x = 1
def f2():
global x # 在函数内部将x标记为全局变量,如果存在则复用,不存在则创建全局变量
x = 2
print(x)
f2()
print(x)
==========================================
def f2():
global x # 在函数内部将x标记为全局变量,如果存在则复用,不存在则创建全局变量
x = 2
print(x)
f2()
print(x)
示例3:
x = int(input("Enter a number:"))
if x > 0:
y = 4 # 全局变量 只有在x>0的条件下创建
print(y)
Enter a number:-10
Traceback (most recent call last):
File "C:/Users/HENG/Desktop/PythonCode/Day04/FunctionTest05.py", line 52, in
print(y)
NameError: name 'y' is not defined
示例4:
sum = 0
for i in range(5): # i 全局变量
sum += i
print(i) # --> 4