更改类(装饰器,元类,其他选项?)中所有方法的参数值

问题描述 投票:0回答:1

我想在将每个参数传递给类方法之前对其进行清理。现在我有点像这样:

from cerberus import Validator
class MyValidator(Validator):  # Validator - external lib (has it's own _validate methods)
def _validate_type_name(self, value):
    # validation code here
    # goal - to clean up value before passing to each methods (mine + from lib) e.g., value.strip() 
schema = {"name": {"type": "name"}, # custom type
          "planet_type": {"type": "string"}} # external lib type
my_dict = {"name": " Mars ", 
           "planet_type": " terrestrial "}
v = MyValidator(schema)
print(v.validate(my_dict))  # True/ False
# NOTE: I would like to do cleanup on method type level (not pass to schema)

我想在传递给MyValidator方法(例如,简单剥离)之前清理数据,但我不想将其作为一个单独的步骤(以防万一有人在调用验证之前忘记执行数据)。我想将清理与验证方法(外部方法+我的方法)集成在一起。

我在考虑使用类的修饰器还是使用元类,但是也许有更好的方法。我在这里没有太多经验,需要您的意见。

python python-3.x decorator metaclass
1个回答
0
投票

如果您的目标是确保调用者进行清理(即,您希望他们“清理”自己的值副本,而不是让您将修改后的版本返回给他们,则这必须在函数之外进行) ,那么装饰器除了执行之外不能做太多事情-即,您可以包装所有函数,以便在传递无效值时引发运行时异常。

我要解决的而不是装饰器的方法是使用类型(这要求您在测试过程中包括mypy,但是无论如何,IMO都应该这样做)。类似于:

from typing import NewType

CleanString = NewType('CleanString', str)

clean(value: str) -> CleanString:
    """Does cleanup on a raw string to make it a 'clean' string"""
    value = value.strip()
    # whatever else
    return CleanString(value)


class MyValidator(Validator):
    def validate_name(self, value: CleanString) -> bool:
        # this will now flag a mypy error if someone passes a plain str to it,
        # saying a 'str' was provided where a 'CleanString' was required!

静态类型的优点是,甚至在执行代码之前,无论实际运行时值如何,都会引发错误。

© www.soinside.com 2019 - 2024. All rights reserved.