04-python 学习第四点-装饰器

装饰器就是一个函数,他是通过不修改某个函数的源代码和调用方式的前提下可以添加新功能的一种函数。在python 中装饰器一般采用高阶函数和嵌套函数达到装饰的作用,下面进行实例讲解:

1、目前有一个网址有很多页面(比如:index,home,bbs)。因为时老文字,所有页面都是可以直接浏览的。实现效果如下:

def home():#模拟网页homne
    print("wolcome to home")

def bbs():#模拟网页bbs
    print("wolcome to bbs")

index() #调用index
home()  #调用home
bbs()   #调用bbs

  运行结果如下:各个网站均可以直接浏览

wolcome to index
wolcome to home
wolcome to bbs

2、公司有了新规定要求主页indezx 保留原始状态直接浏览,home 和bbs 需要登录才能浏览,不允许修改目前的函数源代码和调用方式实现这个功能。这下则么办呢?

我们可以为需要登录才能浏览的网页home 和bbs 函数进行装饰即可。

user, passwd = ‘dwdar‘, ‘abc123‘  # 模拟用户名密码数据库

def auth(func):  # 登录装饰器
    def wrapper():
        username = input("UserName:").strip()
        password = input("Password:").strip()
        if user == username and passwd == password:
            print("登录成功")
            func()
        else:
            exit("验证失败!")

    return wrapper

def index():
    print("wolcome to index")

@auth  # home 被装饰(没有修改源代码和调用方式)
def home():
    print("wolcome to home")

@auth  # bbs被装饰(没有修改源代码和调用方式)
def bbs():
    print("wolcome to bbs")

index()
bbs()
home()

  运行结果:

index 直接可以显示

wolcome to index

随后要求输入用户名和密码,登录后才能浏览home 和bbs

UserName:dwdar
Password:abc123
登录成功
wolcome to bbs
UserName:dwdar
Password:abc123
登录成功
wolcome to home

3、通过几年的发展,网站又有了新的要求,home 这个函数需要返回值了,需要我们更新以下装饰器。

假设home的返回值是这样的。

@auth  # home 被装饰(没有修改源代码和调用方式)
def home():
    print("wolcome to home")
    return "from home"  #home 需要返回值

  目前的装饰器是无法实现返回值的,我们对装饰器进行如下升级即可打印返回值了。

 1 # Author:Dwdar
 2
 3 user, passwd = ‘dwdar‘, ‘abc123‘  # 模拟用户名密码数据库
 4
 5
 6 def auth(func):  # 登录装饰器
 7     def wrapper(*args,**kwargs):
 8         username = input("UserName:").strip()
 9         password = input("Password:").strip()
10         if user == username and passwd == password:
11             print("登录成功")
12             res = func(*args,**kwargs)
13             return res
14         else:
15             exit("验证失败!")
16
17     return wrapper
18
19
20 def index():
21     print("wolcome to index")
22
23
24 @auth  # home 被装饰(没有修改源代码和调用方式)
25 def home():
26     print("wolcome to home")
27     return "from home"  # home 需要返回值
28
29
30 @auth  # bbs被装饰(没有修改源代码和调用方式)
31 def bbs():
32     print("wolcome to bbs")
33
34
35 index()
36 bbs()
37 print(home())       #打印home的返回值

4、又过了一段时间,网站又有了新变化,要求BB 用本地认证系统登录,而BBS需要ldap 认证服务器登录。这下怎么办呢?

第一步:首选我们想到调用装饰器需要传参,通过装饰器参数来判断调用方式。调用装饰器如下。

def index():
    print("wolcome to index")

@auth(auth_type="local")  # 装饰器需要传参,通过参数判断登录方式
def home():
    print("wolcome to home")
    return "from home"

@auth(auth_type="ldap")  # 装饰器需要传参,通过参数判断登录方式
def bbs():
    print("wolcome to bbs")

第二步:装饰器再添加一层函数 outer_wrappr 来接收相关参数最终可以实现判断。

完整代码如下:

# Author:Dwdar
‘‘‘
有一个网址有多个页面,大部分页面时直接浏览的。比如index
后来有了新的要求:
要对home 和页面BBS页面登录才能预览。通过装饰器需要给home 和BBS 添加登录的功能怎么做呢?

‘‘‘

user, passwd = ‘dwdar‘, ‘abc123‘
bbsuser, bbspasswd = ‘bbs‘, ‘bbs123‘  # 模拟ldap 认证账号

def auth(auth_type):
    # print("auth func:", auth_type)

    def outer_wrappr(func):
        def wrapper(*args, **kwargs):
            # print("wrapper func arges:", *args, **kwargs)
            if auth_type == "local":
                username = input("UserName:").strip()
                password = input("Password:").strip()
                if user == username and passwd == password:
                    print("登录成功")
                    res = func(*args, **kwargs)
                    return res
                else:
                    exit("验证失败!")
            elif auth_type == "ldap":
                username = input("bbsUserName:").strip()
                password = input("bbsPassword:").strip()
                if bbsuser == username and bbspasswd == password:
                    print("登录成功")
                    res = func(*args, **kwargs)
                    return res
                else:
                    exit("BBS验证失败!")

        return wrapper

    return outer_wrappr

def index():
    print("wolcome to index")

@auth(auth_type="local")  # 装饰器需要传参,通过参数判断登录方式
def home():
    print("wolcome to home")
    return "from home"

@auth(auth_type="ldap")  # 装饰器需要传参,通过参数判断登录方式
def bbs():
    print("wolcome to bbs")

index()
bbs()
print(home())

运行结果:

wolcome to index
bbsUserName:bbs
bbsPassword:bbs123
登录成功
wolcome to bbs
UserName:

通过判断登录BBS需要输入用户名:BBS的账号和密码才能进入。

原文地址:https://www.cnblogs.com/dwdar/p/11691256.html

时间: 2024-08-30 18:11:15

04-python 学习第四点-装饰器的相关文章

Python学习之路-装饰器&生成器&正则表达式

装饰器 通俗的讲,装饰器就是在不改变源代码基础上,给源代码增加新功能. 不改变函数的源代码.调用方式.返回值等,给函数增加新功能. 经典案例:登录装饰器, def login_decorator(func):     def inner():         if USER_TEMP["status"] == False:             print("\033[31;1m用户未登录,请先登录\033[0m")             login_atm()

python学习笔记(五):装饰器、生成器、内置函数、json

这周学习了装饰器和生成器,写下博客,记录一下装饰器和生成器相关的内容. 一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面每个函数都加一个功能,用来统计每个函数的运行时间是多少,找出来运行比较慢的函数,来优化代码,就需要添加一个新的功能,来统计程序的运行时间,那这样的话,就得修改每个函数了,需要改代码,但是代码特别多,改完了公司倒闭了,这时候装饰

python学习笔记:装饰器2

python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 直接举例: import datetime def func_name(func):#定义一个装饰函数,接受一个函数对象作为参数(也就是被装饰的函数) def wrap():#包装函数 print("Function name:%s"%(func.__name__)) func() #执行目标函数 return wrap #返回包装函数 @func_name #等于 func_time = func_n

Python学习笔记012——装饰器

1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为"装饰器"(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函数,函数装饰类,类装饰函数,类装饰类(两者不是一一对应关系,其实我也不知道他们之间是什么样的对应关系) 一般而言,主要应用的是函数装饰函数 1.3 装饰器本质 本质上,decorator就是一个返回函数的高阶函数. 在面向对象(OOP)的设计模式中,decorator被称为装饰模式.OOP

python学习笔记之装饰器(语法糖)

什么是装饰器 装饰器的知识点铺垫(函数即变量,高阶函数,嵌套函数) 不带参数的装饰器示例 带参数的装饰器示例 作业 一.什么是装饰器 本质上,装饰器就是返回一个函数的高阶函数.装饰器就是一个函数 装饰器的原则: 不修改被装饰对象的源代码 不修改被装饰对象的调用方式 二.装饰器涉及的知识点 函数即变量 高阶函数 嵌套函数 函数即变量: 在python中,一个变量首先被定义,分配内存空间,然后再使用. 以x=1,这个简单的赋值语句为例子.首先在内存中分配一个空间,x指向该内存空间,该内存空间内存入"

从零开始的Python学习Episode 11——装饰器

装饰器 装饰器是用来处理其他函数的函数,主要作用是在不修改原有函数的情况下添加新的功能,装饰器的返回值也是一个函数对象. 简单的装饰器 1 import time 2 3 def show_time(f): 4 def inner(): 5 start = time.time() 6 f() 7 end = time.time() 8 print('time: %s'%(end-start)) 9 return inner 10 11 @show_time 12 def fun1(): 13 p

python学习笔记之——装饰器及对象

1.反射之__import__ 我们知道import语句是用来导入外部模块的,当然还有from...import...也可以,但是其实import实际上是使用builtin函数__import__来工作的.        在一些程序中,我们可以动态地去调用函数,如果我们知道模块的名称(字符串)的时候,我们可以很方便的使用动态调用. __import__(module_name[, globals[, locals[, fromlist]]]) #可选参数默认为globals(),locals()

python高级编程之装饰器04

from __future__ import with_statement # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #with和contextlib #对于要确保即使发生一个错误时也能运行一些清理代码而言,try...finally语句很有用,对以下场景,如: """ 关闭一个文件, 释放一个锁 创建一个临时代码补丁 在特殊环境中运行受保护代码 ----------- with语句覆盖

Python 函数式编程、装饰器以及一些相关概念简介

Python 中的 Decorator(装饰器) 是对一个函数或者方法的封装,从而使其可以完成一些与自身功能无关的工作. 预备知识 一切皆对象 在 Python 中,所有的一切都被视为对象,任何的变量.函数.类等都是 object 的子类.因此除了变量之外,函数和类等也可以被指向和传递. >>> def foo(): ... pass ... >>> def Foo(): ... pass ... >>> v = foo >>> v