函数
函数是用来完成可组织的,重复功能或相关联的单一功能的代码段,它可以提高应用的模块化,提高代码的可在用性 减少代码的重复率。
函数定义
def 函数名(参数):
函数体
return 表达式 #该条语句可以没有
参数
函数可使用的正式参数有以下四种类型:
1.必需参数
2.关键字参数
3.默认参数
4.不定长参数
必需参数
必需参数要求必须和函数声明的顺序保持严格一致,否则会引发异常
关键字参数
关键字参数与函数的调用紧密相关,它使得在函数调用时,具体的参数顺序可以和声明的函数参数顺序不一致,因为 python中可以按照关键字自动匹配相关参数
#!/usr/bin/python3
def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
名字: runoob
年龄: 50
默认参数
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )
名字: runoob
年龄: 50
------------------------
名字: runoob
年龄: 35
不定长参数
python3中你可以调用比函数声明时多的额外的参数,那些为定义的参数会统一以元组的形式存储在*号开头的参数中
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vartuple)
# 调用printinfo 函数
printinfo( 70, 60, 50 )
输出:
70
(60, 50)
还有一种是带两个的参数,那些未定义的参数会以字典的形式存储在开头的参数中
def printinfo( arg1, **vardict ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vardict)
# 调用printinfo 函数
printinfo(1, a=2,b=3)
输出:
1
{'a': 2, 'b': 3}
值得注意的是,声明函数时 号可以单独出现,但是号后面的参数必须以关键字参数传入
>>> def f(a,b,*,c):
... return a+b+c
...
>>> f(1,2,3) # 报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
参数传递
函数传递参数的方式和参数本身是可变类型还是不可变类型有关,如果参数为数字、元组、字符串,则触发值传递,如果参数为 可变类型如列表,字典等,则发生引用传递
匿名函数
python3允许匿名函数的存在,顾名思义,这样的函数不在使用def关键字进行明显声明,而是使用lambda进行声明,它的定义有点类似于C++的宏定义
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
相加后的值为 : 30
相加后的值为 : 40
变量作用域
python3中并不是那个变量在任何位置都可以访问的,访问权限决定于这个变量在哪里赋值的,变量的作用域决定了那一段程序段可以访问哪些变量,python中 变量的作用域一共分为四种:
1.L (local) 局部作用域
2.E (Enclosing)闭包函数外的函数中
3.G (global)全局作用域
4.B (built-in)内置作用域 (一般值模块内)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:
>>> if True:
... msg = 'I am from Runoob'
...
>>> msg
'I am from Runoob'
>>>
msg在if语句内定义的但是在外部依然可以访问到
>>> def test():
... msg_inner = 'I am from Runoob'
...
>>> msg_inner
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'msg_inner' is not defined
msg定义在函数内,则不能访问
局部变量和全局变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域,局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。 调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。
total = 0 # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2 # total在这里是局部变量.
print ("函数内是局部变量 : ", total)
return total
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)
函数内是局部变量 : 30
函数外是全局变量 : 0
global 和 nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num)
1
123
123
如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
100
100