#!/usr/bin/env python # -*- coding: utf-8 -*- # 函数的作用: # 1.代码重用 # 2.流程分解 # 例1:函数的定义和调用 def bar(): print('hello world') bar() # 例2:函数参数 2.1 形参与实参 def add(x,y): #x,y是形参 print (x+y) add(3,5) #3,5是实参 2.2参数顺序 def people(name,age): print ('Name:',name) print ('Age:',age) people('Tom',23) #参数的传入是有顺序的。形参与实参的顺序要一一对应 2.3关键字参数 def people(name,age): print ('Name:',name) print ('Age:',age) people(age=12,name='Bob') 2.4默认参数 def people(name,age,sex='boy'): print ('Name:',name) print ('Age:',age) print ('Sex:',sex) people('Tom',23) 2.4不定长参数 >>> def bar(*arg): ... print(arg) ... >>> bar(1,2,3) (1, 2, 3) 2.5**kwargs 接收键值对参数 >>> def bar(**kwargs): ... print (kwargs) ... >>> bar(name='Tom',age=18) {'name': 'Tom', 'age': 18} 2.6参数的位置 >>> def bar(name,age,sex='boy',*args,**kwargs): ... print(name,age,sex,args,kwargs) Tom 18 1 (2, 3, 4) {'city': "xi'an"} >>> bar('Tom',18,1,2,3,4,city="xi'an") Tom 18 1 (2, 3, 4) {'city': "xi'an"} >>> bar('Tom',18,'boy',1,2,3,4,city="xi'an") Tom 18 boy (1, 2, 3, 4) {'city': "xi'an"} # 例3:函数的多态 def add(x,y): print (x+y) add(3,5) add('hello','world') # 例4:嵌套函数 def bar(): def foo(): print("hello world") foo() bar() # 例5:作用域法则LEGB # L-Local(function);函数内的名字空间 # E-Enclosing function locals;外部嵌套函数的名字空间(例如closure) # G-Global(module);函数定义所在模块(文件)的名字空间 # B-Builtin(Python);Python内置模块的名字空间 # 例6:global语句 x = 88 def bar(): global x x = 99 bar() print (x) # 例7:nonlocal ————用于嵌套函数中 def bar(): x = 1 def foo(): nonlocal x x += 1 foo() print(x) bar() # 例8:闭包(closure):在一个内部函数对在外部的作用的作用域进行一个引用,那么内部函数就是一个闭包 >>> def maker(N): ... def action(X): #一个内部函数 ... return X ** N #N为上级函数的一个变量 ... return action ... >>> f = maker(2) >>> f <function maker.<locals>.action at 0x000002C47A1E2A60> >>> f(3) 闭包的三个特点: 1.闭包函数必须有内嵌函数 2.内嵌函数需要引用该嵌套函数上一级namespace中的变量 3.闭包函数必须返回内嵌函数 # 例9:函数的返回值 9.1 默认返回None >>> def bar(): ... print ("hello") ... >>> f = bar() hello >>> print(f) None 9.2 指定返回值 >>> def bar(): ... print("hello") ... return 1 ... >>> f = bar() hello >>> print(f) 1 9.3 返回计算结果 >>> def bar(x,y): ... return x + y ... >>> f = bar(1,2) >>> print(f) 3 9.4 结束函数 >>> def bar(): ... print("hello") ... return 1 ... print("world") >>> bar() hello 1 9.5 返回元组 >>> def bar(x,y): ... return x,y ... >>> bar(1,2) (1, 2) return的作用: 1.结束函数 2.返回某个对象 # 例10:三元函数 >>> print('hello') if True else False hello # 例11:高阶函数 11.1 变量名可以指向函数 >>> abs(-10) 10 >>> f = abs >>> f(-10) 10 11.2 函数名可以作为其他函数的参数 >>> def bar(x,y,f): ... return f(x)+f(y) ... >>> bar(-5,-3,abs) 8 11.3 函数名可以作为返回值 >>> def bar(): ... def foo(): ... return "hello" ... return foo ... >>> bar() <function bar.<locals>.foo at 0x00000194EED32A60> # 例12:装饰器(Decorator):1.在代码运行期间增加功能;2.不改变源代码 1.在运行期间增加新功能 def hello(): print("hello") def show_time(func): print("------------") func() print("------------") show_time(hello) # 或者如下 # hello = show_time(hello) # hello # 但调用方式还是发生了改变 但是这样改变个源函数的调用方式 2.让hello接收函数名 #如果把一个函数名赋值给hello,hello()就可以执行函数了, #关键问题是如何让show_time(hello)作为函数名赋值给hello #想想高阶函数中函数名可以作为返回值返回的特性 #可以吧上述的函数改为如下 def hello(): print("hello") def show_time(func): def inner(): print("------------") func() print("------------") return inner #此时如果调用show_time,返回的就是inner函数的函数名 hello=show_time(hello) #将inner函数赋值给hello hello() #实际执行的是inner函数 3.@bar #在python中hello=show_time(hello)可以写为@show_time,如下: def show_time(func): def inner(): print("------------") func() print("------------") return inner @show_time def hello(): print("hello") hello() 4.装饰器的参数 def show_time(func): def inner(name): print("------------") func(name) print("------------") return inner @show_time def hello(name): print("hello",name) hello('Bob') 5.函数中嵌套装饰器 import time def logger(flag=''): def show_time(func): def inner(*args,**kwargs): start = time.time() time.sleep(1) func(*args,**kwargs) end = time.time() print('running time:',end - start) if flag == 'true': print('this is loggger') return inner return show_time @logger('true') def foo(*args,**kwargs): sums = 0 for i in args: sums += i print(sums) @logger() def bar(): print('bar..') foo(1,2,3) bar() 6.6 源函数名称的问题————functools.wraps的作用 def show_time(func): def inner(name): print("------------") func(name) print("------------") return inner @show_time def hello(name): print("hello",name) print(hello.__name__) >>inner 源函数的名称变成了inner,不是原来的hello,通过引入wraps解决这个问题 改进如下: from functools import wraps def show_time(func): @wraps(func) def inner(name): print("------------") func(name) print("------------") return inner @show_time def hello(name): print("hello",name) print(hello.__name__) >>hello 6.7装饰器实例 import sys from functools import wraps USERNAME, PASSWORD = 'root','123' no_login = True def login(func): @wraps(func) def inner(*args,**kwargs): global no_login if no_login: print('您还没有登录,请登录---') username = input('username:').strip() password = input('password:').strip() if USERNAME == username and PASSWORD == password: no_login = False else: print('user or password is wrong !') sys.exit() func(*args, **kwargs) return inner @login def home(): print('恭喜来到京东主页') @login def phone(): print('这里是手机专卖') @login def book(): print('这里是图书商店') main = """ 1.home 2.phone 3.book 请选择要进入的主页 """ while True: print(main) choice = input(">>:").strip() if choice == '1': home() elif choice == '2': phone() elif choice == '3': book() else: sys.exit() 总结:装饰器三要素:LEGB、高阶函数、闭包
Python学习笔记——函数
猜你喜欢
转载自www.cnblogs.com/rockley/p/9088338.html
今日推荐
周排行