Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器

目录


一、函数对象

1.函数是第一类对象

#第一类对象的特性:
#
可以被引用 # 可以当做参数传递 # 返回值是函数 # 可以当做容器类型的元素
# def func():
#     print('from func')
#可以被引用
# f=func()
#可以被当做参数
# def bar(x):
#     print(x)#func内存地址
#     x()
# bar(func)

#当做返回值
# def bar(x):#x=func
#     return x #return func
#
# res=bar(func)#res=func
# print(res)
# res()
View Code

2.取代多分支if

用多分支if时

 1 def auth():
 2     print('登陆。。。')
 3 
 4 def register():
 5     print('注册。。。')
 6 
 7 def search():
 8     print('查看。。。')
 9 
10 def interactive():
11     while True:
12         print('''
13         1.登陆
14         2.注册
15         3.查看''')
16         choice=input('>>>').strip()
17         if choice=='1':
18             auth()
19         elif choice=='2':
20             register()
21         elif choice=='3':
22             search()
23         else:
24             print('输入非法')
25 
26 l=[auth,register,search,interactive,]
27 l[3]()
View Code

取代多分支if时

 1 def auth():
 2     print('登陆。。。')
 3 
 4 def register():
 5     print('注册。。。')
 6 
 7 def search():
 8     print('查看。。。')
 9 
10 def transfer():
11     print('转账。。。')
12 
13 def interactive():
14     while True:
15         print('''
16         1.登陆
17         2.注册
18         3.查看
19         4.转账
20         ''')
21         choice=input('>>>').strip()
22         dic={
23             '1':auth,
24             '2':register,
25             '3':search,
26             '4':transfer,
27         }
28         if choice in dic:
29             dic[choice]()
30         else:
31             print('输入非法')
32 
33 interactive()
View Code

二、函数的嵌套

1.函数的嵌套调用

def max(x,y):
    return x if x > y else y

def max4(a,b,c,d):
    res1=max(a,b)
    res2=max(res1,c)
    res3=max(res2,d)
    return res3
print(max4(1,2,3,4))
View Code

2.函数的嵌套定义

def func1():
    print(1)
    def func2():
        print(2)
        def func3():
            print(3)
        func3()
    func2()
func1()

    函数嵌套调用的应用:

db_path='db.txt'
def uname():
    while True:
        uname = input('username>>>').strip()
        if not uname.isalnum():continue
        with open(r'%s'%db_path,'r',encoding='utf-8')as f:
            for line in f:
                if line.startswith(uname):
                    print('该用户已注册,请重新输入')
                    break
            else:
                return uname

def upwd():
    while True:
        upwd1=input('password>>>').strip()
        upwd2=input('confirm password>>>').strip()
        if upwd1==upwd2:
            return upwd1
        else:
            print('输入不一致,请重新输入')

def balance():
    balance=input('请输入充值金额>>>').strip()
    if balance.isdigit():
        return balance

def db_handle(*args):
    info=':'.join(args)
    with open(r'%s'%db_path,'a',encoding='utf-8') as f:
        f.write('%s
' %(info))

def interactive():
    username=uname()
    password=upwd()
    user_balance=balance()
    return username,password,user_balance

username,password,user_balance=interactive()
print(username)
print(password)
print(user_balance)

db_handle(username,password,user_balance)

三、名称空间与作用域

名称空间

1.什么是名称空间,名称空间的分类及其各自特点

'''
名称空间是用于存放名字与值绑定关系的地方(内存地址)。
名称空间可分为三类:
   1.内置名称空间(python解释器自带名字)
          具有全局性、解释器启动生效,关闭则失效
    2.全局名称空间(顶头写的,没有任何缩进、文件级别的,名称在文件执行时就生效,文件结束或名称引用计数为0的时候就失效)
          不是内置的,也不是在函数内的
    3.局部名称空间
           函数的参数以及函数内的名字都存放在局部名称空间,在函数调用时临时生效
'''

2.名称空间的加载顺序

#1、python解释器先启动,因而首先加载的是:内置名称空间
#2、执行test.py文件,然后以文件为基础,加载全局名称空间
#3、在执行文件的过程中如果调用函数,则临时产生局部名称空间

3.名字查找的顺序

'''
查找名字(以局部为开始):
    局部》全局》内置
'''
x=2
def f1():
    x=3
    def f2():
        # x=4
        def f3():
            print(x)
        f3()
        # x=5
    f2()
f1()#打印x=4

作用域

'''
作用域分为两类:
    1.全局作用域:
        包含:内置、全局
        特点:在任何位置都能访问到、伴随程序整个生存周期
    2.局部范围
        包含:局部
        特点:只能在函数内使用、调用函数时生效,结束调用就失效
'''

四、闭包函数

'''
闭包函数就是定义在函数内的函数,并且该函数包含对外部函数作用域中名字的引用。
闭包函数打破了原本函数嵌套的层级限制,能在外面或其它函数里用。闭包函数的作用域关系是在函数定义阶段就被规定死了,与其调用位置无关。接下来我们就来试一下:
'''
def outter():
    x=3
    def inner():
        print('from inner',x)
    return inner
x=4
f=outter()
f()#返回from inner 3

五、装饰器

为什么要用装饰器?

开放封闭原则:
    对修改源代码封闭,对扩展功能开放

什么是装饰器?

装饰器就是在不修改源代码与调用方式的前提下,为被装饰对象增加新功能。
装饰器与被装饰对象均可以是任意调用的对象。

装饰器的使用:

 1 import time
 2 
 3 def timmer(func):#专门用来接收最原始的被装饰函数
 4     #func=index
 5     def inner(*args,**kwargs):
 6         start_time=time.time()
 7         res=func(*args,**kwargs)#调用最原始的被装饰函数
 8         stop_time=time.time()
 9         print('run time is %s'%(stop_time-start_time))
10         return res
11     return inner
12 
13 @timmer#index=timmer(index)将被装饰函数当作参数传给timmer
14 def index():
15     time.sleep(2)
16     print('welcome to index page')
17     return 789
18 
19 @timmer#home=timmer(home)将被装饰函数当作参数传给timmer
20 def home(name):
21     time.sleep(4)
22     print('welcome <%s> to home page'%name)
23     return name
24 @timmer#about=timmer(about)将被装饰函数当作参数传给timmer
25 def about():
26     time.sleep(5)
27     print('this is a detail page')
28     return 456
29 
30 
31 index()
32 home(input('username>>>').strip())
33 about()
无参
 1 import time
 2 userinfo={
 3     'username':None,
 4 }
 5 file_path=r'db.txt'
 6 def timmer(func):
 7     def inner(*args,**kwargs):
 8        start_time=time.time()
 9        res=func(*args,**kwargs)
10        stop_time=time.time()
11        print('run time is %s'%(stop_time-start_time))
12        return res
13     return inner
14 
15 def wauth(engine):
16     def auth(func):
17         def inner(*args,**kwargs):
18             if engine=='file':
19                 if userinfo['username']:
20                     print('用户已登陆')
21                     res = func(*args, **kwargs)
22                     return res
23                 while True:
24                     uname=input('username>>>').strip()
25                     pwd=input('password>>>').strip()
26                     with open(file_path,'r',encoding='utf-8') as f:
27                         for line in f:
28                             user=line.strip('
').split(',')
29                             if uname==user[0] and pwd==user[1]:
30                                 print('登陆成功')
31                                 userinfo['username']=uname
32                                 res=func(*args,**kwargs)
33                                 return res,uname
34                             else:
35                                 print('用户名或密码错误')
36             elif engine=='mysql':
37                 print('基于MySQL认证')
38             elif engine=='ldap':
39                 print('基于LDAP认证')
40             else:
41                 print('认证失败')
42         return inner
43     return auth
44 
45 @timmer
46 @wauth('file')
47 def index():
48     time.sleep(3)
49     print('welcome to index page')
50 
51 @timmer
52 @wauth('file')
53 def home():
54     time.sleep(1)
55     print('welcome to home page')
56 
57 index()
58 home()
有参
原文地址:https://www.cnblogs.com/qiaoqianshitou/p/8663369.html