简体   繁体   English

装饰器类以测试所需的类变量

[英]Decorator class to test for required class variables

First of all I don't know if this is the right approach. 首先,我不知道这是否是正确的方法。 I want to write a decorator class that will be used with methods of other class. 我想编写一个装饰器类,该装饰器类将与其他类的方法一起使用。 Before running the method I'd like to check if all required class variables are initialized. 在运行该方法之前,我想检查是否所有必需的类变量都已初始化。 The ideal case would be something similar to this: 理想的情况将类似于以下内容:

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

If this is not the way it should be done please advise me how to do it properly. 如果这不是应该采取的方法,请告诉我如何正确进行。

I'd say decorators are a bit unfit here for the purpose of checking if a variable exists. 我想说装饰器在这里有点不合适,目的是检查变量是否存在。

Think about what you're planning to do if the required variables are not supplied: raise an exception (it's in your comment). 考虑一下如果没有提供必需的变量,您打算做什么:引发一个异常(在您的评论中)。

I'd say (based on the code above): 我会说(基于上面的代码):

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

And let it fail if self.a or self.b is not supplied (it will raise a NameError exception, you can catch that if you like, and you could raise your own then if you want.) 如果未提供self.a或self.b,则使其失败 (它将引发NameError异常,可以根据需要捕获该异常,如果需要,可以引发自己的异常。)

If you insist on checking before the decorated method's body starts, the following is one reasonable way to do it...: 如果您坚持在装饰方法的主体开始之前进行检查,则以下是一种可行的方法...:

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()

This emits, as you apparently desire, 如您所愿,这发出了

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM