2016-02-25 98 views
2

我导入一些模块Foo并使用该模块中定义的类Foo。该类具有功能f,其调用另一功能g,该模块Foo自己从module_with_g进口。我想重新定义在实例化Foo时使用的g的定义。这里有3个文件显示情况。如何重新定义我在python中导入的函数使用的函数?

Foo.py

from module_with_g import g 

class Foo: 
    def f(self): 
     x = 'bar' 
     g(x) 

module_with_g.py

def g(x): 
    print(x + x) 

module_with_modified_Foo_f.py

import Foo 

def new_g(x): 
    print(x + x + x) 

if __name__ == '__main__': 
    foo = Foo.Foo() 
    foo.f() 

运行最后一个脚本给出barbar。我想要的是让foo.f使用我自己的功能,而不是它的g,我期望得到barbarbar

我在这方面的尝试是尝试使用装饰器以某种方式重新定义foo.f,但我没有任何运气。

module_with_modified_Foo_f.py

import Foo 

def new_g(x): 
    print(x + x + x) 

def redefine_f(f): 
    def redefined_f(*args, **kwargs): 
     return f(*args, **kwargs) 
    #redefined_f.g = new_g 
    return redefined_f 

if __name__ == '__main__': 
    foo = Foo.Foo() 
    # foo.f = redefine_f(foo.f) 
    # foo.__dict__['g'] = new_g # another approach 
    foo.f() 
+4

除了事实,即它是脏的;)我想一起试试看吧'Foo.g = new_g'其中'Foo'是模块,而不是类。 –

+0

为什么你需要这样做?如果是用于测试,可以使用['unittest.mock.patch()'](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)。如果不考虑重新设计你的程序,因为在运行时改变功能是一种可以接受的方式。 ;) –

+0

@YaroslavAdmin这是我不需要改变我正在使用的一些库的实际源代码。 – bourbaki4481472

回答

4

我能做到这一点简单地说,我已经在module_with_modified_Foo_f.py

修改为 Foo.g = new_g
import Foo 
def new_g(x): 
    print(x + x + x) 
Foo.g = new_g 
if __name__ == '__main__': 
    foo = Foo.Foo() 
    foo.f() 

我得到的结果 - barbarbar

1

如果你真的想Foo.py是完全按照你写的,你可以使用下面的module_with_modified_Foo_f.py

import module_with_g 

def new_g(x): 
    print(x + x + x) 

module_with_g.g = new_g 

import Foo 

if __name__ == '__main__': 
    foo = Foo.Foo() 
    foo.f() 

Foo没有按”如果它已经被导入,则第二次重新导入module_with_g,所以这可以被利用。

+0

谢谢,这正是我想要做的。 – bourbaki4481472

+2

其实,我认为@AlokThakur解决方案更清洁,更优雅,现在我看到了它。你不需要使用它随机转换导入语句,所以我建议你使用它。 – werkritter