什么是函数
函数:实际上就是一段具有特定功能、完成特定任务的程序,以减少重复编写程序段的工作量。
定义函数
-
语法
def 函数名(参数1,参数2,参数3,...): '''函数注释''' 代码1 代码2 代码3 reture 返回值 #定义函数发生的事情: 1、申请内存空间,把函数提保存起来, 2、将函数的内存地址绑定给函数名 def register(): inp_user = input("请输入您的账号:").strip() inp_pwd = input("请输入您的密码:").strip() inp_money = input("请充值:").strip() with open('db.txt', mode='at', encoding='utf-8') as f: f.write('{}:{}:{}\n' ..format(inp_user,inp_pwd,inp_money)) x = 10 print(x) print(register) #调用 1、根据函数名找到函数的内存地址 2、函数的内存地址()触发函数体代码的运行 函数名()//是支持内存地址+括号 register() #函数定义阶段:只检测语法不执行代码 def func(): print('hello1') # print('hello2' x print('hello3') func() # 四 函数调用阶段:才会执行函数体代码 def foo(): print('from foo') bar() def bar(): print('from bar') foo()
函数定义的三种形式
#有参函数 def foo(x,y): print(x,y) foo(1,2) # 2、无参函数 def foo(): print('hello') foo() # 3、空函数 def foo(): pass #储备知识:函数返回值 def max2(x, y): if x > y: # print(x) return x else: # print(y) return y res = max2(10, 20) print(res * 12) # 注意:函数体内可以有多个return,但是只要执行一次整个函数就会立即终止并且将其后之当做本次的结果返回 def foo(): print('hello1') return 111 print('hello2') return 2222 print('hello3') return 3333 res = foo() print(res)
Reture的三种形式
- 1、return 值:返回一个值
- 2、return 值1,值2,值3:返回一个元组
- 3、没有return、return、return None:默认返回None
def foo(): # return 1,"aa",[1,2,3] pass res = foo() print(res) # 函数调用的三种形式 def foo(x, y): return x + y # 语句形式 foo(1,2) # 表达式 res = foo(1,2) res = foo(1,2) * 10 print(res) # 函数的调用可以当做一个参数传给另外一个函数 res = foo(foo(1, 2), 3) print(res)
函数分类
1、形参:在定义函数阶段括号内指定的参数(变量名),称之为形参。
2、实参:在函数调用阶段,括号内指定的参数(变量值),称之为实参。
def foo(x,y): # x = 1 # y = 2 print(x,y) foo(1,2)
函数参数
def foo():
print(x,y)
foo(1,2,3)
foo(1,)
-
默认形参
- 在函数定义阶段,就已经为某个形参赋值,该形参称之为默认形参
- 特点:调用阶段可以不为其赋值
def foo(x,y=222): print(x,y) foo(111) foo(111,666) # 注意: # 1、可以混用位置形参与默认形参,但是默认形参必须放在后面 # def foo(y=22,x): # 错误 # pass # 2、大多数情况传入的值都应该为对应的形参定义为默认形参, # 对于每次传入的值都可能不一样的,就赢将其对应的形参定义为位置形参 def register(name, age, gender="male"): print(name, age, gender) register("小王", 18) register("小li", 29) register("jack", 39) register("lili", 16, 'female') # 3、默认形参的值尽量定义成不可变类型 # 例1 m = 100 def foo(x,y=m): print(x,y) m = 200 foo(1) #例2 m = [] def foo(x,y=m): print(x,y) m.append(111) foo(1) #例3 def register(name, hobby, hobbies=[]): hobbies.append(hobby) print("%s 的爱好是 %s" % (name, hobbies)) def register(name, hobby, hobbies=None): if hobbies is None: hobbies = [] hobbies.append(hobby) print("%s 的爱好是 %s" % (name, hobbies)) register('egon',"play") register('tom',"read") register('lili',"music")
-
位置实参
-
在函数调用阶段,按照从左到右的顺序依次传入“变量值”
-
特点:按照顺序传值
def foo(x,y): print(x,y) foo(1,2) foo(2,1)
-
-
关键字实参
-
在函数调用阶段,按照key=value的形式赋值
-
特点:可以打乱顺序,但仍可以为指定的形参赋值
def foo(x,y) print (x,y) foo(y=2,x=1) # 注意: # 可以混用位置实参与关键字实参,但是 # 1、关键字实参必须在后 # 2、不能给同一个形参重复赋值 def foo(x,y): print(x,y) foo(1,y=2) foo(y=2,1) foo(1,2,y=3)
-
-
args与**kwargs
在形参中
# *用在形参中: *会将溢出的位置实参存成元组然后赋值给紧跟其后的形参名 def foo(x,*y): print(x) print(y) foo(1,2,3,4,5,6,7) foo(1) def my_sum(*x): # x = (1,2,3) res = 0x: res += i print(res) my_sum(1,2,3) for i in # **用在形参中:**会将溢出的关键字实参存成字典然后赋值给紧跟其后的形参名 def foo(x, **y): # y = {'y': 2, 'z': 3, 'a': 111, 'b': 222} print(x) print(y) foo(1, y=2, z=3, a=111, b=222)
在实参中
#*与**用在实参中:打撒 # *用在实参中: *会将紧跟其后值打撒成位置实参 def foo(x, y, z): print(x, y, z) foo(*[111, 222, 333]) # foo(111,222,333) foo(*"hello") # foo('h','e','l','l','o') # **用在实参中: **后只能跟字典,**会将紧跟其后字典打撒成关键实参 def foo(x, y, z): print(x, y, z) foo(**{'x': 111, 'y': 222, 'z': 333}) # foo(x=111,z=333,y=222) #arge和kwargs def index(a,b,c): print(a,b,c) def wrapper(*args,**kwargs): # args=(1,2,3) kwargs={} index(*args,**kwargs) # index(*(1,2,3) ,**{}) # index(1,2,3) # index(b=2,c=3,a=1) # wrapper(1,2,3) wrapper(b=2,c=3,a=1)
函数嵌套
函数的嵌套调用:
在调用一个函数的过程中,又调用了其他函数
def max2(x,y):
if x > y:
return x
else:
return y
def max4(a,b,c,d):
res1 = max2(a,b)
res2 = max2(res1,c)
res3 = max2(res2,d)
print(res3)
max4(1,2,3,4)
函数的嵌套定义:在函数内有定义一个函数
def f1(): # 定义在函数内部的内容有一个效果:函数外无法访问,只有在函数内才可以访问到
x = 111
print(x)
f1()
# print(x)
def f1():
def f2():
print('from f2')
f2()
f1()
f2()
from math import pi
def circle(radius, mode=0):
def perimiter(radius):
return 2 * pi * radius
def area(radius):
return pi * (radius ** 2)
if mode == 0:
return perimiter(radius)
elif mode == 1:
return area(radius)
circle(3, 0)
函数对象
def foo(): # foo->函数的内存地址
print('from foo')
x = 10 # x->10的内存地址
# 1、可以被赋值
y = x
f = foo
# 2、可以当做参数传入
def f1(func):
print('====>f1')
func()
f1(foo) # f1(函数的内存地址)
# 3、可以当做返回值
def f1(func):
return func
f = f1(foo)
print(f)
# 4、可以当做容器类型的元素
x = 10
l = [x, foo, foo()]
print(l)
l[1]()
#eg:
def login():
print('登录功能'.center(50, '*'))
def register():
print("注册功能".center(50, '*'))
def transfer():
print("转账功能".center(50, '*'))
def withdraw():
print("提现功能".center(50, '*'))
func_dic = {
"1": ['登录功能', login],
"2": ['注册功能', register],
"3": ['转账功能', transfer],
"4": ['提现功能', withdraw],
}
while True:
print("0 退出")
for k in func_dic:
print(k, func_dic[k][0])
choice = input("请输入命令编号:").strip()
if choice == "0":
break
# if choice == '1':
# login()
# elif choice == '2':
# register()
# elif choice == '3':
# transfer()
# else:
# print("输入的指令错误")
if choice in func_dic:
func_dic[choice][1]()
else:
print("输入的指令错误")
名称空间与作用域
- 名称空间:存放名字内存地址和绑定关系的地方
- 内置名称空间:存放python解释器字典的名字
print(len)
print(input)
-
全局名称空间:存放的是顶级的名字,如下x、z、f1、xxx都是
x = 100 def f1(): y = 200 if 10 > 3: z = 300 if True: xxx = 400
-
局部名称空间:存放的是函数定义的名字
def f1(): x = 200 f1()
-
重要结论1:局部Local-》外层函数Enclosing-》全局Global-》内置Builtin
-
L->E->G->B
# 例1: def f1(): # len = 200 print(len) len = 100 f1() print('=====>',len) # 例2:LEGB len = 100 def f1(): # len = 200 def f2(): # len = 300 print(len) len = 1111111111111111111111111111111111111111111 f2() f1()
-
重要结论2:名称空间的嵌套关系是在函数定义阶段、扫描语法时就确定好的,与调用位置无关
# 例1: len = 100 def f1(): # len = 200 def f2(): print(len) return f2 f = f1() # print(f) len = 6666666666666 f() # 例2: len = 100 def f1(): def f2(): print(len) # len = 200 return f2 f = f1() def foo(): len = 77777 f() foo() # 例3 x = 100 def f1(): print(x) x = 200 f1()
总结
-
全局作用域:全局存活,全局有效
内置名字空间、全局名称空间 -
局部作用域:临时存活,局部有效
局部名称空间# =============》 global关键字 l = [] x = 100 def foo(): l.append(333) global x x = 200 foo() print(l) print(x) # =============》 nonlocal关键字 x = 111 def f1(): # x = 222 def f2(): # global x nonlocal x x = 333 f2() print('==========>f1肚子里的x: ', x) f1() print(x)
-
-