更改 class 中所有方法的参数值(装饰器、metaclass、其他选项?)

Change parameter value for all methods in a class (decorator, metaclass, other option?)

我想在将每个参数传递给 class 方法之前清理每个参数。现在我有这样的东西:

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"}, # name - custom type from _validate_type_name
          "planet_type": {"type": "string"}} # 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 方法之前清理数据(例如,简单的条带),但我不想将其作为一个单独的步骤(以防万一有人在调用验证之前忘记执行它) .我想将清理与验证方法(外部的 + 我的)结合起来。

我正在考虑 class 或 metaclass 上的装饰器,但也许有更好的方法。本人经验不多,求指教

如果您的目标是确保调用者进行清理(即您希望他们 "clean" 他们自己的值副本,而不是让您 return 修改版本给他们,这需要它发生在你的函数之外),那么装饰器除了强制执行之外不能做更多的事情 - 即你可以包装所有函数,以便在无效值通过时引发运行时异常。

我将使用类型而不是装饰器来解决这个问题(这要求您在测试过程中包含 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!

静态类型的优点是在代码执行之前就引发错误,而不考虑实际的运行时值。