首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用自变量的类方法装饰器?

使用自变量的类方法装饰器?
EN

Stack Overflow用户
提问于 2012-07-31 07:30:39
回答 5查看 173.9K关注 0票数 223

如何将类字段作为参数传递给类方法上的装饰器?我想要做的是:

代码语言:javascript
复制
class Client(object):
    def __init__(self, url):
        self.url = url

    @check_authorization("some_attr", self.url)
    def get(self):
        do_work()

它抱怨self不存在用于将self.url传递给装饰器的功能。有什么办法可以解决这个问题吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-07-31 07:38:54

是。不是在类定义时传入实例属性,而是在运行时检查它:

代码语言:javascript
复制
def check_authorization(f):
    def wrapper(*args):
        print args[0].url
        return f(*args)
    return wrapper

class Client(object):
    def __init__(self, url):
        self.url = url

    @check_authorization
    def get(self):
        print 'get'

>>> Client('http://www.google.com').get()
http://www.google.com
get

装饰器截获方法参数;第一个参数是实例,因此它读取该实例的属性。如果不想硬编码属性名,可以将属性名作为字符串传递给装饰器,并使用getattr

代码语言:javascript
复制
def check_authorization(attribute):
    def _check_authorization(f):
        def wrapper(self, *args):
            print getattr(self, attribute)
            return f(self, *args)
        return wrapper
    return _check_authorization
票数 283
EN

Stack Overflow用户

发布于 2016-04-30 02:13:03

一个更简洁的示例可能如下所示:

代码语言:javascript
复制
#/usr/bin/env python3
from functools import wraps

def wrapper(method):
    @wraps(method)
    def _impl(self, *method_args, **method_kwargs):
        method_output = method(self, *method_args, **method_kwargs)
        return method_output + "!"
    return _impl

class Foo:
    @wrapper
    def bar(self, word):
        return word

f = Foo()
result = f.bar("kitty")
print(result)

它将打印:

代码语言:javascript
复制
kitty!
票数 65
EN

Stack Overflow用户

发布于 2019-05-27 17:10:17

另一种选择是放弃语法糖,在类的__init__中进行修饰。

代码语言:javascript
复制
def countdown(number):
    def countdown_decorator(func):
        def func_wrapper():
            for index in reversed(range(1, number+1)):
                print(index)
            func()
        return func_wrapper
    return countdown_decorator

class MySuperClass():
    def __init__(self, number):
        self.number = number
        self.do_thing = countdown(number)(self.do_thing)
    
    def do_thing(self):
        print('im doing stuff!')


myclass = MySuperClass(3)

myclass.do_thing()

它将打印

代码语言:javascript
复制
3
2
1
im doing stuff!
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11731136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档