【问题标题】:Decorator class to test for required class variables用于测试所需类变量的装饰器类
【发布时间】:2010-03-10 17:45:54
【问题描述】:

首先我不知道这是否是正确的方法。我想编写一个装饰器类,它将与其他类的方法一起使用。在运行该方法之前,我想检查是否所有必需的类变量都已初始化。理想的情况是这样的:

class Test(object):
    def __init__(self, f):
        self.f = f
        # some magic

    def __call__(self):
        self.f.magically_get_variable(required)
        # do some checks and execute method or throw an exception

class Data(object):
    def __init__(self, a, b):
        self.a = a

    @test
    def sum(self):
        required('self.a', 'self.b')
        return self.a + self.b

如果这不是应该做的方式,请告诉我如何正确地做。

【问题讨论】:

    标签: python decorator


    【解决方案1】:

    我想说装饰器在这里有点不适合检查变量是否存在。

    想想如果没有提供所需的变量,您打算做什么:引发异常(在您的评论中)。

    我会说(基于上面的代码):

    def sum(self):
        return self.a + self.b
    

    如果没有提供 self.a 或 self.b,让它失败(它会引发 NameError 异常,如果你愿意,你可以捕获它,然后你可以提出自己的如果你愿意。)

    【讨论】:

    • +1: NameError 比任何装饰师都能告诉你更多。它是内置的。它总是有效的。
    【解决方案2】:

    如果您坚持在装饰方法的主体开始之前检查,以下是一种合理的方法...:

    import functools
    
    class test(object):
        def __init__(self, requiredvars):
            self.reqs = requiredvars.split()
    
        def __call__(self, f):
            @functools.wraps(f)
            def wrapper(wself, *a, **k):
              missing = set()
              for v in self.reqs:
                if not hasattr(wself, v):
                  missing.add(v)
              if missing:
                msg = 'missing fields: %s' % ','.join(sorted(missing))
                raise valueerror, msg
              return f(wself, *a, **k)
            return wrapper
    
    class data(object):
        def __init__(self, a, b):
            self.a = a
    
        @test('a b')
        def sum(self):
            return self.a + self.b
    
    d = data(23, 42)
    d.sum()
    

    如你所愿,这会发出,

    Traceback (most recent call last):
      File "rev.py", line 29, in <module>
        d.sum()
      File "rev.py", line 16, in wrapper
        raise ValueError, msg
    ValueError: Missing fields: b
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-23
      • 2019-06-11
      • 2020-11-30
      • 2011-07-17
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 2012-08-14
      相关资源
      最近更新 更多