Decorators (work in progress)

import time
# 在定义函数是一样的

def lalaland():
    time.sleep(2)
    print('bed is my best friend')
# 这里定义函数lalaland , 把time.sleep(2) 和print('bed is my best friend') 放入到了 内存中, 并且门牌号是lalaland
# 当你要调用的时候 加上()来调用,例 lalaland()

def deco(func): #高阶函数 将函数名导入
    start_time=time.time()
    func() #调用函数
    end_time=time.time()
    print('Total running time would be %s'%(start_time-end_time))
    return func
a=deco(lalaland) #可以直接将lalaland的内存地址门牌号传入到deco中,func=lalaland,用deco中的func()来调用lalaland
                 #我们可以给lalaland添加一些功能 然后函数的返回值定为门牌号
a() #这样a等同于lalaland 相同的门牌号 
#这边我们就可以不定义为a 而重新定义变量alalaland 来替代最初的lalaland()中的lalaland
lalaland=deco(lalaland)
lalaland() #因此我们可以不改变函数的调用方式的情况下 给函数添加一些新的功能

# 练习
def test_01():
    time.sleep(3)
    print("test_01")
def test_02():
    time.sleep(3)
    print('test_02')
def deco(func):
    start_time=time.time()
    func()
    end_time=time.time()
    print('the total running time is %s'%(end_time-start_time))
    return func

test_01=deco(test_01) 
test_01()

#最终结果练习

def timer(func): #time(test1). test1=func
    def deco(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)#-----------如果函数有返回值,那么这里要定义变量
        end=time.time()
        print('total: %s'%(end-start))
        print('--------do you need to sleep?')
        return res
    return deco

@timer  #@timer=test1=timer(test1)=deco 这样就把test1deco连了一起 这样test1()=deco()
def test1(name,age):
    time.sleep(1)
    print('test1',name,age) 
    return 'I dont need to sleep at all' #如果函数有返回值 那么要在上面

                    #time(test1)=deco=test1
test1('ethan','34') #其实执行的就是deco, test1#我们定义变量为test1这样就替换了原有的test1# = timer(test1)#因为timer的返回值是deco所以=》》# = deco
                                    #所以deco()=test1(), 这样我们添加型参  
#@timer 的作用就是替代下面的给函数定义变量 得到这个例子里deco的内存地址 
# @timer=test1=timer(test1)=deco()=deco
# test1()=deco()
# test1()  

 # 装饰器的高潮学习
import time
user='Ethan'
passwrd='1234'
def auth(auth_type):
    def define(func):
        def exam(*args,**kwargs):
            if auth_type=='local':
                username=input('please enter your username: ')
                password=input('please enter your password: ')
                if username==user and password==passwrd:
                    print('welcome back '+username)
                    a=func(*args,**kwargs)
                    return a
                else:
                    print('your user name is incorrect,please double check')
            elif auth_type=='ldap':
                print('dont know how to use it yet')
        return exam
    return define
 
def index():
    print('welcome')
@auth(auth_type='local') #home_page=auth(auth_type)=define(home_page)=exam
def home_page(): 
    print('welcome back')
    return 'from home'
@auth(auth_type='ldap')
def blog_login():
    print('welcome back, blogger')

index()
home_page()
blog_login()

# ldap 统一认证管理 ssh无密钥认证 






# let write a decorater, this is just a practice, delete later
def dog_kind(kind):
    def dog_01(func):
        def add_detail(*args,**kwargs):
            if kind=='mix':
                # print('-------dog detail----------')
                func(*args,**kwargs)
                question=input('do you love your dog?')
                if question=='yes':
                    print('he is the best dog ever')
                else:
                    print('he is very nauty ') 
            else:
                print('you are not mix')
        return add_detail
    return dog_01

@dog_kind(kind='mix')   #首先将kind传入到dogkind----这样可以找到dog_01的内存地址----然后flower会传入到dog_01# ------这样可以得到add_detail的内存地址  最终我们将flower=add_detail
def flower(name,age,food):
    print('my dog name is: '+name)
    print(name+' age is %s'%(age))
    print('%s loves all different kind of %s'%(name,food))
flower('flower','20','all_food')
  
高阶函数+嵌套函数=装饰器

函数就是‘变量’

a=1 意味着 先定义a变量 这样把1会存储在内存空间中的一个空房间中,并命名这个空房间为a.
这样当调用这个变量时,会重新查找a门牌号(内存中的位置)来寻找出存在a房间中的1

每次定义一个变量 则会在内存中存储这个变量 
因此在调用之前 定义变量的没有顺序 

高阶函数:就是把函数的内存名当成参数传递的一种函数

def add(a,b,c):
    return print(c(a)+c(b))
add(-1,-4,abs)
Ethan Zhaodecorator