优化嵌套类方法中的输入验证

Optimizing Input Verification in Nested Class Methods

提问人:Silverwilly 提问时间:11/11/2023 最后编辑:mkrieger1Silverwilly 更新时间:11/11/2023 访问量:57

问:

我有以下示例类:

class MyClass:
    @classmethod
    def method1(cls, value):
        print(f'method1 called with value: {value}')
        cls.method2(value)
        cls.method3(value)

    @classmethod
    def method2(cls, value):
        print(f'method2 does something with supplied value: {value}')

    @classmethod
    def method3(cls, value):
        print(f'method3 does something with supplied value: {value}')

正如你所看到的,这里有一个嵌套的逻辑。 必须调用方法和 。现在,每次调用任何方法(我还有更多方法)时,我都想验证输入值。我可以定义一个类方法,然后在每个函数的开头调用。但是,这意味着我的输入将被多次验证。method1method2method3cls._verify(cls, value)

如何有效地对一组类方法(包括嵌套调用)执行输入验证,而无需多次冗余验证输入?

我试过了:(1)我尝试添加一个“缓存”参数(即cls._already_verified),该参数将在验证后变为True。这种方法的问题在于,下次运行我的类的另一个方法时,该值仍为 True。 此外,(2) 仅在公共类中调用_verify方法不起作用,因为许多方法都建立在其他公开可用的方法之上。

Python 验证

评论

0赞 mcjeb 11/11/2023
你也在使用_methods吗?因为如果没有,为什么不调用 method1?然后它只叫了一次。cls._verify(cls, value)
0赞 Silverwilly 11/11/2023
感谢您的回复。为了澄清,我改变了问题:method2 和 method3 也应该能够自行调用。因此,将 cls._verify(cls, value) 分别添加到每个方法意味着始终对每个方法执行验证,但当我调用方法 1 时总共 3 次。这是我想防止的。
0赞 Silverwilly 11/11/2023
嗨,@mkrieger1,感谢您的回复。是的,我知道这种方法。然而,问题是 method1(在本例中)建立在 method2 中的逻辑之上,而 method2 同时具有我也希望公开可用的逻辑功能。
0赞 mkrieger1 11/11/2023
顺便说一句,这并不是类方法所特有的。同样的问题可能用普通方法出现,也可以用同样的方式解决。

答:

0赞 Barmar 11/11/2023 #1

添加一个额外的参数,指示是否已通过验证。value

class MyClass:
    @classmethod
    def method1(cls, value, verified=False):
        if not verified:
            cls._verify(value)
        print(f'method1 called with value: {value}')
        cls.method2(value, verified=True)
        cls.method3(value, verified=True)

    @classmethod
    def method2(cls, value, verified=False):
        if not verified:
            cls._verify(value)
        print(f'method2 does something with supplied value: {value}')

    @classmethod
    def method3(cls, value, verified=False):
        if not verified:
            cls._verify(value)
        print(f'method3 does something with supplied value: {value}')

评论

0赞 Silverwilly 11/11/2023
我确实考虑过在类参数cls._verify存储一个标志,该标志将用作缓存,以检查方法 cls._verify() 是否已经运行(我认为这在某种程度上是您所指的)。问题在于,这意味着下次运行另一个方法时,cls_verify仍为 True,同时调用了新方法。
0赞 Barmar 11/11/2023
是的,它必须特定于该调用,它不能是类范围的标志。
2赞 mkrieger1 11/11/2023 #2

您可以将方法的逻辑分为公共层和私有层。公共层负责验证输入,并以其他方式委托给私有层,私有层信任输入已经过验证,并负责实际的应用程序逻辑。

私有方法可以自由调用对方,而无需验证开销。公共方法应该只在验证输入后调用私有方法,而不能调用其他公共方法。

class MyClass:
    @classmethod
    def method1(cls, value):
        print(f'method1 called with value: {value}')
        cls._verify(value)
        cls._method2_no_verify(value)
        cls._method3_no_verify(value)

    @classmethod
    def method2(cls, value):
        cls._verify(value)
        cls._method2_no_verify(value)

    @classmethod
    def method3(cls, value):
        cls._verify(value)
        cls._method3_no_verify(value)

    @classmethod
    def _method2_no_verify(cls, value):
        print(f'method2 does something with supplied value: {value}')

    @classmethod
    def _method3_no_verify(cls, value):
        print(f'method3 does something with supplied value: {value}')