python decorators_python decorators

python decorators

装饰器基础

Decorator 本质

@ 本质是语法糖- Syntactic Sugar

使用@decorator 来修饰某个函数 func 时:

@decorator

def func():

pass

其解释器会解释成:

func = decorator(func)

注意这条语句会被执行

多重装饰器

@decorator_one

@decorator_two

def func():

pass

相当于:

func = decorator_one(decorator_two(func))

带参数装饰器

@decorator(arg1, arg2)

def func():

pass

相当于:

func = decorator(arg1,arg2)(func)

使用 *args、**kwargs 给被装饰函数传递参数

def wrapper(func):

def wrapper_in(*args, **kwargs):

# args是一个数组,kwargs一个字典

print("%s is running" % func.__name__)

return func(*args, **kwargs)

return wrapper_in

@wrapper

def func(parameter1, parameter2, key1=1):

print("call func with {} {} {}".format(parameter1, parameter2, key1))

func("haha", None, key1=2)

# func is running

# call func with haha None 2

带参数的装饰器

def log(level):

def decorator(func):

def wrapper(*args, **kwargs):

if level == "warn":

print("%s with warn is running" % func.__name__)

elif level == "info":

print("%s with info is running" % func.__name__)

return func(*args, **kwargs)

return wrapper

return decorator

@log("warn")

def foo(*args, **kwargs):

print("args {}, kwargs{}".format(args, kwargs))

foo(1, 2, a = 3)

# foo with warn is running

# args (1, 2), kwargs{'a': 3}

等同于

def foo(name='foo'):

print("args {}, kwargs{}".format(args, kwargs))

foo = log("warn")(foo)

方法装饰器

类方法是一个特殊的函数,它的第一个参数 self 指向类实例

所以我们同样可以装饰类方法

def decorate(func):

def wrapper(self):

return "

{0}

".format(func(self))

return wrapper

class Person(object):

def __init__(self):

self.name = "John"

self.family = "Doe"

@decorate

def get_fullname(self):

return self.name+" "+self.family

my_person = Person()

print my_person.get_fullname()

#

John Doe

上例相当于固定了 self 参数,不太灵活

使用 *args, **kwargs传递给 wrapper 更加通用:

def pecorate(func):

def wrapper(*args, **kwargs):

return "

{0}

".format(func(*args, **kwargs))

return wrapper

class Person(object):

def __init__(self):

self.name = "John"

self.family = "Doe"

@pecorate

def get_fullname(self):

return self.name+" "+self.family

my_person = Person()

print my_person.get_fullname()

类装饰器

类实现 __call__ 方法后变成可调用对象,故可以用类做装饰器

class EntryExit(object):

def __init__(self, f):

self.f = f

def __call__(self):

print "Entering", self.f.__name__

self.f()

print "Exited", self.f.__name__

@EntryExit

def func1():

print "inside func1()"

@EntryExit

def func2():

print "inside func2()"

def func3():

pass

print type(EntryExit(None))

# func1 变为类实例

print type(func1)

print type(EntryExit)

# func3 是普通函数

print type(func3)

func1()

func2()

#

#

#

#

# Entering func1

# inside func1()

# Exited func1

# Entering func2

# inside func2()

# Exited func2

类装饰器

@EntryExit

def func1():

print "inside func1()"

等同于

def func1():

print "inside func1()"

# 此处可以看出 func1 是类EntryExit的一个实例

func1 = EntryExit(myfunc1)

装饰器装饰类

register_handles = []

def route(url):

global register_handles

def register(handler):

register_handles.append((".*$", [(url, handler)]))

return handler

return register

@route("/index")

class Index():

def get(self, *args, **kwargs):

print("hi")

# Index 仍然为原来定义的类实例

# 相当于在定义类的同时调用装饰器函数 route, 将该类注册到全局路由 register_handles

@route("/main")

class Main():

def get(self, *args, **kwargs):

print("hi")

print (register_handles)

print(type(Index))

# [('.*$', [('/index', )]), ('.*$', [('/main', )])]

#

@route("/index")

class Index():

def get(self, *args, **kwargs):

print("hi")

Index = route("/index")(Index)

# register 返回传入的 handler,故 Index 仍然为类对象

functools

上述装饰器实现有个问题,就是被装饰函数的属性被改变

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python decorators是一种用于修改或增强函数功能的语法结构。它们允许开发者在不修改原始函数代码的情况下,通过在函数定义之前使用特殊符号(@)和装饰器函数来对函数进行包装或修饰。装饰器函数接受被装饰函数作为参数,并可以在原始函数执行之前或之后添加额外的逻辑或功能。这种技术可以用来实现缓存、日志记录、身份验证等功能。 Python decorators的使用方法可以根据具体需求进行定义和实现。常见的方法包括使用装饰器函数、使用类作为装饰器、使用带参数的装饰器等。装饰器函数是最常见的一种方式,它接受一个函数作为参数并返回一个新的函数,新函数会替换原始函数。这样,在调用原始函数时,实际上是调用了被装饰的函数,从而在不修改原始函数的情况下添加了额外的功能。 除了使用Python内置的装饰器语法,还可以使用第三方库来简化装饰器的编写和使用。例如,可以使用decorator模块来定义和使用装饰器。这个模块提供了一种更简洁的语法,可以直接在函数定义之前使用@decorator语法来应用装饰器。该模块的使用方法如下所示: ```python from decorator import decorator @decorator def hint(func, *args, **kwargs): print('{} is running'.format(func.__name__)) return func(*args, **kwargs) ``` 上述代码定义了一个名为hint的装饰器函数,它接受一个函数作为参数,并在函数执行之前打印出函数名。然后,通过在函数定义之前使用@hint语法,将装饰器应用到目标函数上。这样,在调用目标函数时,实际上会先执行装饰器函数内部的逻辑,然后再执行目标函数本身的逻辑。 总结来说,Python decorators是一种用于修饰函数的语法结构,可以通过装饰器函数在不修改原始函数代码的情况下增强函数功能。它可以通过Python内置的装饰器语法或第三方库来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python Decorator](https://blog.csdn.net/weixin_30951231/article/details/96490117)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Python系列之装饰器(decorator)](https://blog.csdn.net/ikxyang/article/details/121995824)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值