有人知道这个密码有什么问题吗?在
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)
我得到以下错误:
^{pr2}$我之所以认为这是可行的,是因为,通过反复试验,我让下面的装饰器像魅力一样为classmethods工作:
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
这真的很简单,但乍一看很棘手。看pep 318。在
相当于:
^{pr2}$您有一个额外的包装器,它接受一个装饰器的参数来在包装好的函数(closure design pattern)中使用它。所以你的装饰师看起来像这样:
相当于:
你的装饰师有一个额外的间接层次,那就是扔掉东西。执行此操作时:
你要做的是:
^{pr2}$这就是装修工的工作。请注意,
paginated_instance_method
是用get_attending_users
作为参数调用的。这意味着在decorator中,参数default_page_size
被设置为函数paginated_instance_method
。修饰符返回函数wrap
,因此get_attending_users
被设置为wrap
函数。在然后当您调用}是您的事件实例。
Event().get_attending_users()
时,它将调用wrap(self)
,其中{wrap
期望参数是函数,并尝试返回一个包装该函数的新函数。但是参数不是一个函数,而是一个Event
对象,因此functools.wrap
在试图包装它时失败。在我有预感你想做的是:
也就是说,您希望
paginated_instance_method
接受一个参数。但即使您想使用该参数的默认值,您仍然必须实际调用callpaginated_instance_method
。否则,只需将方法作为参数传递,这不是paginated_instance_method
所期望的。在它之所以对classmethod“起作用”,是因为类方法将类作为第一个参数,而类(与实例不同)具有一个
__name__
属性。但是,我怀疑如果您进一步测试它,您会发现它并没有真正做到您想要它做的事情,因为它仍然在包装类而不是方法。在paginated_instance_method
不是decorator,它是一个函数,返回decorator。所以(注意括号。)
相关问题 更多 >
编程相关推荐