我可以在不重写代码的情况下更改Python对象的调用吗?

2024-09-28 19:26:40 发布

您现在位置:Python中文网/ 问答频道 /正文

在伪Python代码中考虑下面的场景:

    class Component_i: # same for i = 1,2,3,...
        __call__(self, input):
            return input
   
    class MyClass:
        def __init__(self):
            self.comp_1 = Component_1()
            self.comp_2 = Component_2()
            self.comp_3 = Component_3()
        def __call__(self, input):
            return self.comp_3(self.comp_2(self.comp_1(input)))
    
    A = MyClass()

现在我想做以下几点:

    class Component_2B:
        __call__(self, input, option = True):
            if option:
                return input
            else:
                return do_stuff_with_input(input)
            
    A.comp_2 = Component_2B()

然后我想将A的__call__更改为也接受可选输入option,并且这个可选输入在调用时传递给A.comp_2。但是为了使事情复杂化,我想在不重写__call__的情况下实现这个

有人有主意吗


这里是一个MWE:

    class MultiplyWithParameter:
        def __init__(self, parameter: float):
            self.p = parameter
        def __call__(self, input: float):
            return self.p * input

    class ProcessDataClass:
        def __init__(self, parameter: float):
            self.mul = MultiplyWithParameter(parameter)
        def __call__(self, input: float):
            input = input * 5 + 4
            input = self.mul(input)
            return input - 3

    DataProcessor = ProcessDataClass(2.5)

    class OptionalMultiplyWithParameter:
        def __init__(self, parameter: float):
            self.p = parameter
        def __call__(self, input: float, multiply: Bool = True):
            if multiply:
                return self.p * input
            else:
                return input

现在我要开始了

    DataProcessor.mul = OptionalMultiplyWithParameter(DataProcessor.mul.p)

并使用DataProcessor(4.23, False)。这将在调用期间将False传递给DataProcessor.mul。我希望在不重写ProcessDataClass__call__的情况下执行此操作(否则将很简单)


以下是一些动机:

假设internet上有一个名为coollibrary的包,我想从中使用函数coolclassfactory。此函数返回CoolClass的实例,该实例具有一系列属性和__call__。它的某些属性可能属于ProcessWithParameters类。初始化时,CoolClass从Internet加载参数。现在我想给出我的CoolClass实例,它是我用coolclassfactory作为MyClass的属性构建的。但是我想用另一个类OptionalProcessWithParameters替换我的CoolClass实例拥有的所有属性以及类ProcessWithParameters的所有属性,这基本上允许在运行时选择两种可能的方法来处理带有参数的输入。因为这个运行时选项是新的,所以我必须在调用过程中添加它(我想?-这很重要,在多处理中使用它应该是安全的!)。现在不幸的是,因为我使用了coolclassfactory,这返回了CoolClass的许多可能的子类中的一个,每个子类都有一个__call__,所以我不能简单地重写__call__,因为这取决于调用coolclassfactory的方式。本质上,我必须重写CoolClass子类的所有调用,我正试图避免


Tags: selfinputreturn属性parameterinitdefcall
1条回答
网友
1楼 · 发布于 2024-09-28 19:26:40

您始终可以将what ever类划分为子类,并根据自己的喜好重写/扩展/调整原始文件的任何部分,并使用super()访问原始功能

根据您的示例,类似于以下示例:

class ProcessDataClassOptional(ProcessDataClass):
    def __init__(self, parameter: float):
        super().__init__(parameter) #use the original init to do its thing
        self._mul = OptionalMultiplyWithParameter(parameter) #our modification

    def __call__(self, input: float, multiply: Bool = True):
        self.mul = lambda x: self._mul(x, multiply) # now the original will use our modify mul
        return super().__call__(input)

现在您可以使用调整后的版本

DataProcessor = ProcessDataClassOptional(2.5)
DataProcessor(4.23)
DataProcessor(4.23, False)

当用作原始行为时,不应该有任何更改,但现在您也可以使用新行为

相关问题 更多 >