Python进阶(七)----带参数的装饰器,多个装饰器修饰同一个函数和递归简单案例(斐波那契数列)

Python进阶(七)----带参数的装饰器,多个装饰器修饰同一个函数和递归简单案例(斐波那契数列)

一丶带参数的装饰器

def wrapper_out(pt):

    def wrapper(func):
        def inner(*args,**kwargs):

            useinput = input('请输入用户名:>>').strip()
            password = input('请输入密码:>>').strip()
            with open(pt,encoding='utf-8') as f:
                for line in f:
                    us,pwd=line.strip().split('|')
                    if useinput==us and password ==pwd:
                        print(f'登录{pt}成功')
                        ret=func()
                        return ret
                return False
        return inner

    return wrapper

@wrapper_out('qq')
def QQ():
    print('welcome QQ')

@wrapper_out('dy')
def Dy():
    print('welcome Dy')


QQ()
Dy()


### 看到带参数的装饰器分两步执行:
#开发思路:增强耦合性
#	  @wrapper_out('qq')
#     1. 执行wrapper_out('qq') 这个函数,把相应的参数'qq' 传给 pt,并且得到返回值 wrapper函数名。
#     2. 将@与wrapper结合,得到我们之前熟悉的标准版的装饰器按照装饰器的执行流程执行。

二丶多个装饰器装饰一个函数

def wrapper1(func1):
    def inner1():
        print('w1 ,before')
        func1()
        print('w1 after')
    return inner1

def wrapper2(func2):
    def inner2():
        print('w2 ,before')
        func2()
        print('w2 after')
    return inner2

@wrapper2   #  f =wrapper2(f) , func2=inner1函数 当执行完func2时, 就带表要去执行inner1,  func1() 执行的是真正的原函数.
@wrapper1   #  f =wrapper1(f) , func1=f原函数   f()=inner1
def f():
    print('in f')

f()        # f在这里 被我定义 变量,看下面理解,就ok了.



#### 推荐一种方式 ,debug模式.     
# 多个装饰器装饰一个函数相当于装饰器函数的嵌套  (相当于把另一个装饰器函数的inner方法作为参数传递给了另一个装饰器函数的形参func接收.) so不明白就看下面吧👇


# 1. 程序从上到下执行, 加载两个函数到内存.  --->  按常理来说应该是先执行wrapper2 ,但是由于wrapper1 靠近被装饰的函数. so 先执行 wrapper1装饰器函数


# 2. 执行 wrapper 1装饰器,   func1 形参接收的是 f原函数的内存地址,  而f(变量)被指向为--->inner1函数内存地址


# 3. 指向wrapper2 装饰器 , func2 形参接收的是 f(变量的内存地址 ,也就是inner1的内存地址), 此时的f(变量)被重新指向为 inner2 函数的内存地址. 


#  加载执行过程:
f(变量)--->inner1,func1形参--->f原函数 ==========>>>> f(变量)----<inner2 ,func2形参---->inner1(inner1函数内存地址被当做参数传给了func2)     


# 取值执行过程:
f(变量)就是inner2 函数执行,  ----> 打印w2 before  -->执行 func2, 也就是执行inner1函数,打印w1 before
----->执行func1形参的值,func1指向的 f原函数 ,打印 f原函数内的东西  ----> 执行完原函数后,返回到inner1函数继续执行----->打印inner1函数 w1 after .------> 执行完inner1函数,返回到inner2函数中,打印 w2 after





###总结快捷解题规律: (最好是画图,快捷,  没有之一.)  
#   1.哪个装饰器在被装饰器函数的最上面. 那个就是最外层.
#   2.一层一层嵌套. 如下图👇:

三丶递归函数

# -*- coding: utf-8 -*-
# Author  : Ds

# 递归函数 : 函数或者其他的代码都可以解决 递归解决的问题 .递归在某些时候有特效
# 官网规定:  默认递归的最大深度1000次
#  如果你递归超过100次还没有解决这个问题,那么执行使用递归,执行效率低

#递归含义:
	# 具有明确的终止条件
	# 自己调用自己

#递归案例一:
 def func(n):
     print(n)
     n+=1
     func(n)
 func(1)

#递归案例二:
def age(n):
    if n ==1:
        return 18
    else:
        return  age(n-1)+2

print(age(4))


#递归案例三:
li= [1, 3, 5, ['太白','元宝', 34, [33, [11,33],55, ]], [77, 88],66]

def func(lis):
    for el in lis:
        if type(el)==list:
         	func(el)
        else:
            print(el)

func(li)



#  return案例
li= [1, 3, 5, ['太白','元宝', 34, [33, [11,33],55, ]], [77, 88],66]
def func(lis):
    for el in lis:
        if type(el)==list:
         	return func(el)     # 只执行到最深的一层列表就返回.
        else:
            print(el)
func(li)



###个人总结: 
# 递归函数 中 , 存在return ,若果 递归函数中首先已经明确 结束条件.  在不适当的位置加了return(人为的终止条件) 就会造成数据的缺失,

###存在return 
#上述例子中, 如果在 条件判断后,return 返回func()函数,
#(个人理解: 简单的例子,for循环嵌套,  外层需要执行9次 ,但是执行到4,内层需要执行9次,内层执行完9次之后.存在return ,执行完内层的9次就直接终止)
# 那么当列表中的数据遇到最深的一层列表,输出完结果就会直接终止函数. 后面的数据就不在被执行
# 也就是说 return就只执行到最深的一层列表.


###不存在return
# 相反,没有return , (个人理解: 简单的例子,for循环嵌套,  外层需要执行9次 ,但是执行到4,内层需要执行9次,内层执行完9次之后.外层继续执行)
# 每次调用递归, 当内层列表都被打印出来之后,外层列表继续下一次

四丶斐波那契数列的几种推导方式

###斐波那契数列的几种推导方式

#递归:

 def fbnq_dg(n):
     if n<=1:                                # 4  逐层递减, 递减拼接相加   ,结束条件是每次的结果值不能小于0,也不能大于1
         return n
     return fbnq_dg(n-1)+fbnq_dg(n-2)        #  [3  2]   -->, [2  1   1 0],    [(1, 0)  (0,0)   (1,0)  (1,0)  ] ,      特点: 一生二,二生四,四生八 ,将最后的所有1相加.就是结果
 for i in range(1,4):
     print(fbnq_dg(i))



# 递推
 def fib_loop(n):
     a,b=0,1
     for i in range(n+1):
         a,b=b,a+b
     return a

 print(fib_loop(4))     # 1 1 2 3 5



#生成器
def fib_lop_while(n):
    a,b=0,1
    while n>0:
        a,b=b,a+b
        yield a
        n -= 1
obj=fib_lop_while(10)         #  生成器 <generator object fib_lop_while at 0x000002898FDFFF68>
print(obj.__next__())	# 1    一次取值,打印一次
print(obj.__next__())    # 1        
print(obj.__next__())    # 1

posted @ 2019-06-25 20:33  染指未来  阅读(299)  评论(0编辑  收藏  举报