【问题标题】:Decorators that make the affected function return false?使受影响的函数返回 false 的装饰器?
【发布时间】:2013-12-05 05:25:44
【问题描述】:

我有一个 Django 函数read_detail,它根据是否允许用户阅读页面返回 True 或 False。该函数在具有不同逻辑的几个不同的类中重复,但有一个逻辑我认为总是相同的,如果用户是超级用户,则返回 True。我想这样设置:

@is_superuser
def read_detail()

如果用户是超级用户,@is_superuser 将强制 read_detail() 返回 True,并且不会进行进一步的评估。然后我可以避免跨类重复这一点逻辑。这可能吗?

【问题讨论】:

  • 查看某个用户是否为超级用户的逻辑是什么?
  • 请考虑给您的函数起一个更合理的名称,例如can_read_details()。现在看起来你的函数会读取一些细节。
  • 在您的特定情况下使用装饰器也是值得怀疑的。我不是很了解背景,但是这两行代码真的很简单易读:if is_superuser(): return True。现在你想删除这 2 条超级简单的线并添加 1 条线,它不知道它实际上做了什么。

标签: python django decorator


【解决方案1】:
class is_superuser(object):

def __init__(self, fn):
    self.fn = fn
    self.is_super = False

def __call__(self, *args, **kwargs):
    if self.is_super: return True
    return self.fn(*args, **kwargs)



>>> @is_superuser
... def blah():
...   return "baz"
... 
>>> blah()
'baz'
>>> blah.is_super = True
>>> blah()
True

【讨论】:

    【解决方案2】:

    我会将谓词逻辑从装饰器中分离出来,类似于

    def true_if(predicate):
        return lambda fun: lambda *a, **k: predicate() or fun(*a, **k)
    

    然后

    def is_superuser():
        return ...your logic....
    
    
    @true_if(is_superuser)
    def read_detail():
    

    同样,您可以定义false_iftrue_unless 等。看起来对我很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 2019-11-05
      • 2020-04-28
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多