实例方法上的Python装饰器

标签 python oop decorator instance-methods

有人知道这段代码有什么问题吗?

def paginated_instance_method(default_page_size=25):
    def wrap(func):
        @functools.wraps(func)
        def inner(self, page=1, page_size=default_page_size, *args, **kwargs):
            objects = func(self=self, *args, **kwargs)
            return _paginate(objects, page, page_size)
        return inner
    return wrap

class Event(object):
    ...
    @paginated_instance_method
    def get_attending_users(self, *args, **kwargs):
        return User.objects.filter(pk__in=self.attending_list)

我收到以下错误:

    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/Users/zarathustra/Virtual_Envs/hinge/hinge_services/hinge/api/decorators.py", line 108, in wrap
        def inner(self, page=1, page_size=default_page_size, *args, **kwargs):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/functools.py", line 33, in update_wrapper
        setattr(wrapper, attr, getattr(wrapped, attr))
    AttributeError: 'Event' object has no attribute '__name__'

我认为这可行的原因是,通过反复试验,我得到了以下装饰器,就像类方法的魅力一样工作:

def paginated_class_method(default_page_size=25):
    def wrap(func):
        @functools.wraps(func)
        def inner(cls, page=1, page_size=default_page_size, *args, **kwargs):
            objects = func(cls=cls, *args, **kwargs)
            return _paginate(objects, page, page_size)
        return inner
    return wrap

最佳答案

paginated_instance_method 不是装饰器,它是一个返回装饰器的函数。所以

@paginated_instance_method()
def get_attending_users(self, *args, **kwargs):

(注意括号。)

关于实例方法上的Python装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15098424/

相关文章:

Python通过装饰类动态给类的方法添加装饰器

python - 替换列表中的特定元素

python - 如何在python中获取5分钟前的时间

java - 异常处理;试着抓

c# - C# 中的默认类可访问性

python - 如何使用 duck typing 编写 OOP 一致的代码?

angular - 为 angular 2+ 创建一个返回服务 http 调用的最后结果的装饰器

python - 装饰器不改变 dir()

python - 如何确定 Python 中对象的大小?

python - 值错误 : no such test method in <class 'myapp.tests.SessionTestCase' >: runTest