如何修改类方法?

时间:2018-06-13 20:16:05

标签: python class object

我希望通过改变它的行为来修改类的方法。请注意,我不希望完全重写另一种方法,因为它很复杂并涉及许多变量并与其他方法交互。这是我正在尝试做的一个例子:

import types
class example_class(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self.pi = 3.14

    def example_method(self):
        print(self.a * self.b * self.c * self.pi)

#Create an instance of the object and call the method.
my_example = example_class(3, 5, 7)
my_example.example_method()

#Now I wish to change the "example_method" to add instead of multiply. 
def different_method(self, a, b, c):
    print(self.a + self.b + self.c + self.pi)

my_example.example_method() = types.MethodType(different_method(10,20,30), my_example)

我尝试使用types.MethodType但上面的方法不起作用。请注意,我试图用different.method()替换example.method()。我想给方法提供不同的值来计算。

编辑: 谢谢所有回答我问题的人!你已经为我澄清了这一点,现在我可以为我的课程做单词!但是,我应该进一步澄清。我希望修改我的方法以包含另一个变量。所以我的different_method应该是这样的:

 #Now I wish to change the "example_method" to add instead of multiply. 
 def different_method(self, a, b, c, extra_variable):
     print(self.a + self.b + self.c + extra_variable + self.pi)

我在添加额外变量时遇到困难 - 如果你能提供一些指导,我将非常感激!

2 个答案:

答案 0 :(得分:3)

你混淆了函数对象,以及调用这些函数返回的值。

首先,在=的左侧,您有:

my_example.example_method()

因此,您不是要替换example_method的{​​{1}}属性,而是尝试分配它返回的任何内容(此处为my_example)。这毫无意义。

然后,在右侧,您正在尝试构建一个方法,而不是None之外的方法,而是调用different_method的结果。这也毫无意义。

你想要的是:

different_method(10,20,30)

现在你可以像任何其他方法一样调用它:

my_example.example_method = types.MethodType(different_method, my_example)

但是,虽然我们处于此状态,但您的my_example.example_method(10, 20, 30) 也没有多大意义。它需要参数different_method,但完全忽略它们,而只是添加a, b, c。虽然这不是非法,但它有点愚蠢 - 这意味着新方法与您要替换的方法没有相同的签名,这必然会引起混淆。所以你可能想要的是:

self.a + self.b + self.c

如果要添加不同的值,您可以创建一个新的示例对象,就像想要乘以不同的值一样:

def different_method(self):
    print(self.a + self.b + self.c + self.pi)

my_example.example_method = types.MethodType(different_method, my_example)

my_example.example_method()

如果您计划进行大量的monkeypatching,您可能需要编写一个函数来修补示例对象:

my_other_example = example_class(10, 20, 30)
my_other_example.example_method = types.MethodType(different_method, my_other_example)
my_other_example.example_method()

...所以你可以这样做:

def patch_example(example, different_method):
    example.example_method = types.MethodType(different_method, example)

(但是,如果您确实需要多次执行此操作,则可能需要创建子类或其他更高级别的抽象。)

答案 1 :(得分:1)

# first you replace the method

my_example.example_method = types.MethodType(different_method, my_example)

# then you call it
my_example.example_method(10,20,30)