函数
数学定义:y=f(x),y是x的函数,x是自变量
Python函数:
1、有若干个语句组成的语句块、函数名称、参数列表构成,它是组织代码的最小单元
2、完成一定的功能
函数的作用:
1、结构化编程对代码的基本的封装,一般按照功能组织一段代码
2、封装的目的为了复用,减少冗余代码
3、代码更加简洁美观、可读易懂
函数的分类:
1、内建函数,如max()、reversed()等
2、库函数,如math.ceil()等
函数定义、调用
def语句定义函数:
def 函数名(参数列表):
函数体(代码块)
[return 返回值]
1、函数名就是标识符,命名要求一样
2、语句块必须缩进,约定4个空格
3、Python的函数没有return语句,隐式会返回一个None值
4、定义中的参数列表成为形式函数,只是一种符号表达,简称形参
调用:
1、函数定义,只是声明了一个函数,它不会被执行,需要调用
2、调用的方式,就是函数名加上小括号,括号内写上参数
3、调用时写的参数是实际参数,是实实在在传入的值,简称实参
函数举例
def add(x,y):
result = x+y
return result
out = add(4,5)
print(out)
1、上面只是一个函数的定义,有一个函数叫做add,接收2个参数
2、计算的结果,通过返回值返回
3、调用通过函数名add加2个参数,返回值可使用变量接收
4、定义需要在调用前,也就是说调用时,已经被定义过了,否则抛NameError异常
5、函数是可调用对象,callable()
函数参数:
参数调用时传入的参数要和定义的个数相匹配(可变参数例外)
位置参数:
1、def f(x,y,z)调用使用f(1,3,5)
2、按照参数定义顺序传入实参
关键字参数:
1、def f(x,y,z)调用使用f(x=1,y=3,z=5)
2、使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同
f(z=None,y=10,x=[1])
f((1),z=6,y=4.1)
备注:要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的
参数默认值:
1、定义时,在形参后跟上一个值
2、def add(x=4,y=5):
return x+y
add(6,10),add(5,y=9),add(x=3),add(),add(y=8),add(x=1,y=2),add(y=2,x=100)
举例:
定义一个函数login,参数名称为host、port、username、password
def login(host='127.0.0.1',port='80',username='eric',password='123456'):
print('{}:{}@{}/{}'.format(host,port,username,password))
login()
login('127.0.0.1',80,'eric','123456')
login('localhost',username='root')
login('localhost',port=3306,password='123456')
login(port=80,password='123456',host='172.16.15.100')
可变参数:
累加求和的问题
def add(nums):
sum = 0
for x in nums:
sum += x
return sum
add([1,3,5])
add((2,4,6))
传入一个可迭代对象,迭代元素求和
一个形参可以匹配任意个参数
位置参数的可变参数:
有多个数,需要累加求和
def add(*nums):
sum = 0
print(type(nums))
for x in nums:
sum += x
print(sum)
In [68]: add(3,6,9)
<class 'tuple'>
18
在形参前使用*表示该形参是可变参数,可以接收多个实参
函数的返回值
举例:
def showplus(x):
print(x)
return x+1
showplus(5)
执行结果为:5
def showplus(x):
if x > 3:
return ">3"
else:
return "<=3"
print(showplus(5))
返回:>3
例子:
def showplus(x):
if x > 3:
return x
else:
print("{} is not greater than 3".format(x))
print(showplus(2))
返回:
2 is not greater than 3
None
def showplus(x):
if x > 3:
return x
else:
print("{} is not greater than 3".format(x))
print(showplus(5))
返回值为:5
总结:
1、Python函数使用return语句返回“返回值”
2、所有函数都有返回值,如果没有return语句,隐式调用return None
3、return语句并不一定是函数的语句块的最后一条语句
4、一个函数可以存在多个return语句,但是只有一条可以被执行。如果没有一条return语句被执行到,隐式调用return None
5、如果有必要,可以显示调用return None,可以简写为return
6、如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其它语句就不会被执行了
7、作用:结束函数调用、返回值
返回多个值:
def showplus():
return [1,3,5]
showplus()
print(showplus())
打印出:[1,3,5]
def showplus():
return 1,3,5
showplus()
print(showplus())
打印出:(1, 3, 5)
1、函数不能同时返回多个值
2、return[1,3,5]是指明返回一个列表,是一个列表对象
3、return 1,3,5看似返回多个值,隐式的被Python封装成了一个元组
使用解构提取出来,将更加方便和明白
def showplus():
return 1,3,5
x,y,z = showplus()
print(x,y,z)
打印结果为:1 3 5
函数嵌套
在一个函数中定义了另外一个函数
def fn():
def add():
print("add")
print("fn")
add()
fn()
打印结果为:
fn
add
def fn():
def add():
print("add")
print("fn")
add()
fn()
add()#这个是会报错的,因为函数有可见范围,也就是作用域,内部的函数不能被外部直接使用,会抛出NameError异常
作用域
1、一个标识符的可见范围,这就是标识符的作用域。一般常说的是变量的作用域
x = 6
def fn():
print(x)
fn()
返回值打印结果为:6
x = 6
def fn():
#x = 3
x += 1
print(x)
fn()
注:如果把x=3注释掉,就会报语法错误
原因:x += 1其实就是x = x + 1,相当于在fn内部定义一个局部变量x,那么fn内部所有x都是这个局部变量x了,但是这个x还没有完成赋值,就被拿来做加1操作了
全局作用域:
在整个程序运行环境中都可见
局部作用域:
1、在函数、类等内部可见
2、局部变量使用范围不能超过其所在的局部作用域
嵌套解构
def fn():
o =65
def add():
print("add{}".format(o))
print(chr(o))
print("fn{}".format(o))
add()
fn
打印结果:
fn65
add65
A
def fn():
o =65
def add():
o = 97
print("add{}".format(o))
print(chr(o))
print("fn{}".format(o))
add()
fn()
打印结果为:
fn65
add97
a
从以上嵌套的例子可以看出:
1、外层变量作用域在内层作用域可见
2、内层作用域中add,如果定义了o=97,相当于当前作用域中重新定义了一个新变量o,但是这个o并没有覆盖外层作用域fn中的o
例子:
x = 6
def fn():
#x = 4
y = x + 1
#x += 1
print(x)
fn()
注:如果把x += 1前面的#号取消掉,同样还是报错,是因为x还没有完成赋值,就被拿来做加1操作了
全局变量global:
x = 6
def fn():
global x
x += 1
fn()
print(x)
返回值:7
原因:使用global关键字的变量,将fn内的x声明为使用外部的全局作用域中定义的x;全局作用域中必须有x的定义
#x = 6
def fn():
global x
x = 10
x += 1
print(x)
fn()
print(x)
返回结果为:
11
11
原因:使用global关键字的变量,将fn内的声明为使用外部的全局作用域中定义的x;但是,x=10赋值即定义,x在内部作用域为一个外部作用域的变量赋值,所以x+=1不会报错,但是需要注意的是,这里的x作用域还是全局的。
global总结
x += 1这种是特殊形式产生的错误,先引用,后赋值,而python动态语言是赋值才算定义,才能被引用。在语句之前加上x=0之类赋值语句,或者使用global告诉内部作用域,去全局作用域查找变量定义。
内部作用域使用x=5之类的赋值语句会重新定义局部作用域使用的变量x,但是,一旦这个作用域中使用global声明x为全局的,那么x=5相当于在为全局作用域的变量x赋值。
global使用原则:
1、外部作用域变量在内部最用于可见,但也不要在这个内部的局部作用域中直接使用,因为函数的目的就是为了封装,尽量与外界隔离。
2、如果函数需要使用外部全局变量,请使用函数的形参传参解决
3、一句话:不用global。学习知识为了深刻理解变量作用域
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/87818