ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python装饰器

2022-08-17 23:03:29  阅读:176  来源: 互联网

标签:__ python self print foo 装饰 def


1. 简介

​ Python中的装饰器是一种可以装饰其它对象的工具。类似于装饰模式,实际是对原有对象进行功能上的增强(原有对象可以是对象、函数、类)。其使用像java 的注解。

​ 该工具本质上是一个可调用的对象(callable),所以装饰器一般可以由函数、类来实现。装饰器本身需要接受一个被装饰的对象作为参数,该参数通常为函数、方法、类等对象。装饰器需要返回一个对象,该对象可以是 经过处理的原参数对象、一个包装且类似原参数的对象;或者返回一个不相干内容。

​ 基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内置函数),执行函数时再在内层函数中执行闭包中的原函数。可以在你改变函数内部代码和调用的前提下,实现在函数执行和执行拓展功能。

​ 适用于多个函数系统统一在执行前后定义一些功能。

2. 简单使用

  1. 基于类实现装饰器,对函数进行增强
# 简单装饰器。 基于类实现装饰器,对函数进行增强
class wrap(object):
    def __init__(self):
        pass

    def __call__(self, obj):
        print("======1")
        print(obj)
        print("======2")
        return obj


@wrap()  # 等价于 foo = wrap(foo)
def foo():
    print('hello decorator!')


print(foo())

结果:

======1
<function foo at 0x0000021FDBB9EF70>
======2
hello decorator!
None
  1. 基于函数实现装饰器,对函数进行增强
# 简单装饰器。 基于函数实现装饰器,对函数进行增强
def wrap(obj):
    print("======1")
    print(obj)
    print("======2")
    return obj


@wrap  # 等价于 foo = wrap(foo)
def foo():
    print('hello decorator!')


print(foo())  

结果:

======1
<function foo at 0x000002171B1F1F70>
======2
hello decorator!
None
  1. 给被装饰的对象添加一个name 属性, 并且值设置为 张三
# 装饰器-给被装饰的对象添加一个name 属性, 并且值设置为 张三
def wrap(obj):
    obj.name = '张三'
    return obj


@wrap
class User:
    def __int__(self):
        pass


print(User.name)  # => hello decorator!
print(User)

结果:

张三
<class '__main__.User'>
  1. 函数装饰器: 对传入的对象进行增强,增强后返回新的对象
# 函数装饰器: 对传入的对象进行增强,增强后返回新的对象
def outer(func):
    def inner():
        print("hello inner")
        func()

    return inner


@outer  # foo = outer(foo)
def foo():
    print('hello foo')


print(foo.__name__)
foo()  # => hello foo

结果:

inner
hello inner
hello foo
  1. 对象方法装饰器。和普通的函数装饰器的区别是多了一个默认的self 参数
# desc: 对象方法装饰器。和普通的函数装饰器的区别是多了一个默认的self 参数

def outer(obj):
    def inner(self):
        print('hello inner')
        obj(self)

    return inner


class Zoo(object):
    def __init__(self):
        pass

    @outer  # => zoo = outer(zoo)
    def zoo(self):
        print('hello zoo')


zoo = Zoo()
print(zoo.zoo.__name__)
zoo.zoo()

结果:

inner
hello inner
hello zoo
  1. 类方法装饰器。 相当于对类进行增强
# desc: 类方法装饰器。 相当于对类进行增强

def outer(clss):
    class Inner(object):
        def __init__(self):
            self.clss = clss()

        def __getattr__(self, attr):
            return getattr(self.clss, attr)

    return Inner


@outer  # Zoo = outer(Zoo)
class Zoo(object):
    def __init__(self):
        pass

    def say(self):
        print('hello world!')


zoo = Zoo()
print(zoo.__class__)
zoo.say()

结果:

<class '__main__.outer.<locals>.Inner'>
hello world!
  1. 特殊应用的装饰器,比如,类静态属性装饰器。 如下代码可以看出ratio 会作为一个属性,而不是方法
class Foo(object):
    def __init__(self, height, weigth):
        self.height = height
        self.weigth = weigth

    @property
    def ratio(self):
        return self.height / self.weigth


foo = Foo(176, 120)
print(foo.ratio)

自己实现:

class Prop(object):
    def __init__(self, fget):
        self.fget = fget

    def __get__(self, instance, owner):
        return self.fget(instance)


class Foo(object):
    def __init__(self, height, weigth):
        self.height = height
        self.weigth = weigth

    @Prop
    def ratio(self):
        return self.height / self.weigth


foo = Foo(176, 120)
print(foo.ratio)
  1. 装饰带参数和返回值的对象
# desc: 装饰带参数和返回值的对象

# def outer(func):  # 函数装饰器
#     def inner(x, y):
#         print('hello inner')
#         return func(x, y)
#
#     return inner


def outer(func):  # 函数装饰器
    def inner(*args, **kwargs):
        print('hello inner')
        return func(*args, **kwargs)

    return inner


@outer
def add(x, y):
    return x + y


print(add(1, 4))

结果:

hello inner
5
  1. 装饰器本身带参数
# desc: 装饰器本身带参数

url_mapping = {}


def route(url):
    def decorator(func):  # 函数装饰器
        url_mapping[url] = func
        return func

    return decorator


@route('/home')
def home():
    print(1)
    pass


@route('/index')
def index():
    print(2)
    pass


print(url_mapping)

结果:

{'/home': <function home at 0x000001B16D480D30>, '/index': <function index at 0x000001B16D48F040>}

标签:__,python,self,print,foo,装饰,def
来源: https://www.cnblogs.com/qlqwjy/p/16572879.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有