def关键字 空格 函数名(与变量设置相同): 英文的冒号
函数体
执行函数 :函数名+()
函数是以功能为导向的,
def login():
pass
def register():
pass
函数的返回值。
return: 1,函数中遇到return 结束函数,下面代码不执行。
def login():
print(111)
print(222)
return
print(333)
login()
#输出:
111
222
2,将函数里面的值返回给函数的执行者(调用者)。
第一种情况:
只有return,返回None
def log():
print(111)
print(222)
return
print(log())
#输出:
111
222
None
第二种情况:
return None
def log():
print(111)
print(222)
return None
print(log())
#输出:
111
222
None
第三种情况:
return 单个值(返回的值与单个值的类型相同)
def login():
a = 1
b = 2
return a #输出:1 int
return [666] #输出: 【666】 list
print(login(),type(login()))
第四种情况:
return 多个值 以元组的形式返回给函数的调用者。
def log():
a=1
b=2
return 1,['a',2],'abc'
print(log(),type(log()))
#输出:(1, ['a', 2], 'abc') <class 'tuple'>
函数的参数。
def my_len(a): #a 形参
count = 0
for i in a:
count += 1
return count
l1 = [1, 2, 3, 1, 6, 9, 100]
print(my_len(l1)) #l1 实参
# 实参角度
位置参数
def tes(a, b, c):
print(111)
print(a, b, c)
tes(22, 'alex', [11, 22, 33])
#位置一一对应 实参形参数量相等
一一对应,实参形参数量相等
关键字参数
def func(x, y,):
print(x, y)
func(y=3333, x=4)
#一一对应,实参形参数量相等,实参顺序可变
混合参数 (位置参数,关键字参数)
def func(x, y, z):
print(x, y, z)
func(11, 22, z=111)
#输出:11 22 111
#关键字参数必须在位置参数后面
关键字参数必须在位置参数后面
#三元运算
x = 100
y = 30
if x > y:
print(x)
else:
print(y)
x = 100
y = 20
c = x if x > y else y
print(c)
#三元算法,简化了很多
# 形参角度
位置参数
一一对应,实参形参数量相等
默认参数
def func2(y, x, z=100):
print(x, y, z)
func2(1, 2, 3000)
#输出:2 1 3000
#默认参数必须放在形参的位置参数后面,默认参数不传值则为默认值,传值则覆盖默认值
def func2(y, x, z=100):
print(x, y, z)
func2(1, 2)
#输出:2 1 100
默认参数必须放在形参的位置参数后面
默认参数不传值则为默认值,传值则覆盖默认值。
def input_information(name, sex='男'):
with open('information',encoding='utf-8', mode='a') as f1:
f1.write('{}\t{}\n'.format(name, sex))
while True:
msg = input('请输入用户的姓名,性别\Q或者q退出').strip()
if msg.upper() == 'Q':break
if ',' in msg:
name, sex = msg.split(',')
input_information(name, sex)
else:
input_information(msg)
动态参数
用户传入到函数中的实参数量不定时,或者是为了以后拓展
此时要用到动态参数 *args **kwargs,(万能参数)
def func1(*args,**kwargs):
pass
func1()
不会报错
*args接受的是所有的位置参数
**kwargs接收的是所有的关键字参数
def func1(*args, **kwargs):
print(args)
print(kwargs)
func1(1, 2 ,3, 4)
func1(x =4, y= 5, z = 6)
func1(1,2,3,x = 4, y = 5, z = 6)
#输出:(1, 2, 3, 4)
{}
()
{'x': 4, 'y': 5, 'z': 6}
(1, 2, 3)
{'x': 4, 'y': 5, 'z': 6}
# 位置参数,*args,默认参数
def func2(a, b, *args, sex='男'):
print(a)
print(b)
print(args)
print(sex)
func2(1, 2, 5,6,7,8,9,sex='女')
#输出:
1
2
(5, 6, 7, 8, 9)
女
# 位置参数,*args,默认参数, **kwargs
def func2(a, b, *args, sex='男',age=20, **kwargs):
print(a)
print(b)
print(args)
print(sex)
print(age)
print(kwargs)
func2(1, 2, 5, 6, 7, 8, 9, x=6, y=5, name='alex')
#输出:
1
2
(5, 6, 7, 8, 9)
男
20
{'x': 6, 'y': 5, 'name': 'alex'}
#***
# 函数的定义 *用意是聚合。
# 在函数的执行时,*的用意是打撒。
def func3(*args,**kwargs): # 函数的定义 *用意是聚合。
print(args)
print(kwargs)
l1 = [1, 2, 3]
tu1 = (1, 2, 3)
tu2 = (11, 22, 33)
func3(*l1, *tu1, *tu2) # 在函数的执行时,*的用意是打散。
#输出:(1, 2, 3, 1, 2, 3, 11, 22, 33)
#名称空间,加载顺序,函数嵌套
当程序运行时,代码从上至下一次读取,遇到变量和值,
他会在内存中开辟一个空间,存放变量与值得内存地址的对应关系。
这样存储变量与值的对应关系的空间叫做名称空间(命名空间)。
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;
当解释器遇到函数时,他会将函数名存储到内存中,但是对于函数体莫不关心。
当函数执行时,他会通过函数名找到函数体,然后将函数题里面的变量等对应关系存放在一个
临时开辟的空间中,随着函数的结束,临时的空间关闭,这样的空间叫做临时名称空间。
内置名称空间:
len(), print(),input(),list
作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
名称空间:
内置名称空间
全局名称空间
局部名称空间
加载顺序:内置名称空间 ---> 全局名称空间(程序运行时) ---->局部名称空间(函数执行时)
作用域:
全局作用域:内置名称空间 全局名称空间
局部作用域:局部名称空间
取值顺序(单向):局部名称空间(函数执行时) ---> 全局名称空间 ---> 内置名称空间
L local 局部,本地
E eclose
G global 全局的
B Built-in 内置的
#built-in 内置
sum = 666 # global
def func1():
sum = 555 # eclose
print(sum)
def inner():
pass
sum = 111 # local
# print(sum)
inner()
func1()
print(111)
def func1():
name = 'alex'
print(name)
def inner():
a = 2
print(a)
print(444)
inner()
print(555)
print(222)
func1()
# 加载顺序
#输出:
111
222
alex
444
2
555
def func1():
a = 666
print(666)
def func2():
name = 'taibai'
print(name)
func1()
print(333)
func2()
print(555)
#输出:
333
taibai
666
555
函数的嵌套
#global和nonlocal
#global
在全局名称空间里得到局部名称空间的变量
1,return
2,global
# 1,在局部作用域中声明一个全局变量。
def func1():
name = 'alex'
print(name)
print(name) #输出:报错,因为全局空间里没有name
def func1():
global name
name = 'alex'
func1()
print(name)
#输出:alex 在局部作用域中声明一个全局变量( 相当于给全局空间里添加一个name)
# 2,在局部作用域中,更改一个全局变量。
name = '老男孩'
def func1():
global name
name = 'alex'
func1()
print(name)
#输出:alex
# 补充:
# 对于可变的数据类型,函数中如果对其进行操作,改变全局不用引用global.
l1 = [1, 2, 3]
def func1():
l1.append(666)
func1()
print(l1)
#输出:[1, 2, 3, 666]
# nonlocal
#1,不能改变一个全局变量。
name = "老男孩"
def func1():
nonlocal name
print(name)
func1()
#因为不能改变一个全局变量,所以报错
# 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,
# 并且引用的那层,从那层及以下此变量全部发生改变。
name = "老男孩"
def func1():
name = 'alex'
print(name) # 1, alex
def inner():
nonlocal name
name = '老男孩'
print(name) # 2 老男孩
inner()
print(name) # 3,alex 老男孩
func1()
#输出:alex
老男孩
老男孩
def add_b():
b = 42
def do_global():
b = 10
print(b)
def dd_nonlocal():
nonlocal b
b = b + 20
print(b)
dd_nonlocal()
print(b)
do_global()
print(b)
add_b()
#输出:
10
30
30
42
#函数名的应用
1.直接打印函数名得到的是函数的内存地址
def func():
print(222)
func()
print(func)
#输出:222
<function func at 0x0000019670B21E18>
2.函数名可以赋值运算
def func1():
print(666)
f1 = func1
f1()
#输出:666
3.函数名可以作为函数的参数
def func1():
print(666)
def func2(x):
x()
print(555)
func2(func1)
#输出:
666
555
4.函数名可以作为容器类数据类型的元素
def func1():
print(666)
def func2():
print(222)
def func3():
print(111)
def func4():
print(777)
1 = [func1, func2, func3, func4]
for i in l1:
i()
#输出:
666
222
111
777
5.函数名可以当做函数的返回值
def func1():
print(666)
def func2(x):
print(222)
return x
ret = func2(func1)
ret()
#输出:222 666