1.python中函数定义的方法:
def test(x):
“the function definition“
x+=1
return x
def:定义函数的关键字
test:函数名
():内可定义形参
“ ” :文档描述(非必要,但是建议为你的函数添加描述信息)
x+=1:泛指代码块或程序处理逻辑
return:定义一返回值
2.函数的优点:
代码重用
保持一致性,易维护
可扩展性
3.对于一个函数:
返回值数=0(即没有定义的函数中没有return) :调用后返回None
返回值数=1: 返回object(返回那个值)
返回值数>1(如 return 1 ‘jiao’ [1 2 ] ):返回一个元组
4.函数的参数:
(1)形参变量只有在被调用是才分配内存单元,在调用结束后,即刻释放所分配的内存单元。因此,形参只有在函数内部有效,函数调用结束返回主调用函数后则不能再使用该形参变量。
(2)实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,他都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值、输入等办法使参数获得确定值
(3)位置参数 必须一一对应,缺一不可
def test(x,y,z): print(x) print(y) print(z) 调用:test(1,2,3)
运行结果: 1 2 3
(4)关键字参数 即调用时 test(y=1,x=2,z=3) 无需一一对应,缺一不可
注:位置参数和关键字参数混合使用时,位置参数必须再关键词参数左边
(5)默认参数 (此处 type 即默认参数,,不用对其赋值也能运行,当对其赋值时, type 就变为位置参数了)
def handle(x,type=None): print(x) print(type) handle('hello')
运行结果:
hello
None
(6)参数组:** (字典)(接收键值对或者 **字典)、 * (列表)(接收数字、字符串、列表、元组、字典以及 *元组 ,不接收键值对)
def test(x,*args):
print(x)
print(args)
test(1,2,3.4,5)
test(1,[1 ,2, 3 ])
test(2,*(1,2,3))
运行结果:
1
(2, 3.4, 5) 多余元素全部传给args,以元组的形式存在
1
([1, 2, 3],) 整个列表看作元组的一个元素
2
(1, 2, 3) 前边加 * ,传给args的每个元素依次输出
def test(x,**kargs):
print(x)
print(kargs)
test(1,y=2,z=3) test(1,x=2,y=3,z=3)会报错:一个参数不能传两个值(x)
test(2,**{'k1':'jiao','k2':2}) 若想传值给**kargs,只有两种形式,传入键值对,即 k1=jiao,或者**{‘k1’:‘jiao’}
运行结果:
1
{'y': 2, 'z': 3}
2
{'k1': 'jiao', 'k2': 2}
def test(x,*args,**kwargs):
print(x)
print(args,args[-1])
print(kwargs,kwargs.get('y'))
test(1,*[1,2,3],**{'y':1})
test(1,1,[7,8],2,3,*[4,5,6],y=1,**{'z':2})
运行结果:
1
(1, 2, 3) 3
{'y': 1} 1
1
(1, [7,8],2, 3, 4, 5, 6) 6
{'y': 1, 'z': 2} 1
5.全局变量和局部变量
(1)顶头定义的变量即为全局变量,缩进定义的变量即局部变量
name = 'jiaoguohua' def change_name(): name = '帅的一批' print('change_name',name) change_name() print(name)
运行结果:
change_name 帅的一批 此处输出的时局部变量
jiaoguohua 此处时全局变量 可知,在子程序中修改不会影响到全局变量(子程序中的name与全局变量中的name不是一个)
(2)再子程序中调用 global 即可在子程序中修改全局变量
name = 'jiaoguohua'
def change_name():
global name
name = '帅的一批'
print('change_name',name)
change_name()
print(name)
运行结果:
change_name 帅的一批
帅的一批
注1 (在子程序中,如果调用某个变量,程序会先在子程序中找此变量,若子程序中没有,在在全局中找此变量)
注2 (如果函数内容无global关键字,则优先读取局部变量,能读取全局变量,无法对全局变量进行赋值,但是能够对内部元素进行操作,此时全局变量也被修改
如果函数中又global关键字,变量本质上就是全局那个变量,可读取可赋值)
name = ['jiaoguohua']
def change_name2():
name.append('帅的一批')
print(name)
change_name2()
print(name)
运行结果:
['jiaoguohua', '帅的一批']
['jiaoguohua', '帅的一批'] 全局变量也被修改了
注3 (在一个函数中有global关键字并对某个全局变量做出修改时,只有当此函数被调用才会发生全局变量被修改)
name = 'jiaoguohua'
def change_name1():
global name
name = '帅的一批'
print(name)
def change_name2():
name = '丑的一批'
print(name)
print(name)
change_name2()
change_name1()
print(name)
运行结果:
jiaoguohua
丑的一批
帅的一批
帅的一批
6.函数内部可以嵌套函数
运行步骤
NAME = '海风' 1 def huangwei(): 2 name = '黄伟' 3.1 print(name) 3.2 def liuyang(): 3.3 name = '刘洋' 3.4.1 print(name) 3.4.2 def nulige(): 3.4.3 name = '胡志华' 3.4.5.1 print(name) 3.4.5.2 print(name) 3.4.4 nulige() 3.4.5 liuyang() 3.4 print(name) 3.5 huangwei() 3
运行结果:
黄伟
刘洋
刘洋
胡志华
黄伟
(1)关键词 nonlocal : 指定上级变量(在多层嵌套的函数中 nonlocal 指定上一级变量,而无论嵌套多少层,global都是指定全局变量)
name = '杠娘'
def weihou():
name = '沉着'
def weiweihou():
nonlocal name
name = '冷静'
print(name)
weiweihou()
print(name)
print(name)
weihou()
运行结果:
杠娘
冷静
冷静
7.前向引用:
def foo():
print('from foo')
bar()
def bar():
print('from bar')
foo()
运行结果:
from foo
from bar
并不会报错,因为在调用之前 foo() 和 bar() 都已经被加载到内存当中。若 foo() 在 def foo(): 和 def bar(): 之间,则会报错
8.函数的作用域
def foo():
name = 'inf'
def bar():
name = 'wupeiqi'
def tt():
print(name)
return tt return tt 即返回 tt函数的内存地址 (把函数的内存地址赋值给一个变量,则 变量+()就可执行此函数)
return bar
bar = foo()
tt=bar()
tt()
print(tt)
运行结果: 上面三行相当于 foo()()()
wupeiqi
<function foo.<locals>.bar.<locals>.tt at 0x000001975CB98B70> tt函数的内存地址