修补内置方法或类

时间:2018-07-13 10:07:25

标签: python mocking built-in

我想在调用np.random.seed的代码中找到所有实例(不使用grep)。为了在ipdb中设置断点,我尝试使用

查找源文件
import inspect; inspect.getsourcefile(np.random.seed)

,但是它引发TypeError,因为它是内置方法(因为它是用C编码的)。

是否可以通过修改主源文件中的内容来观看对np.random.seed的任何调用? 另外,例如,修补该方法将是合适的。另外记录它(或调用调试器):

def new_random_seed(seed):
    """
    This method should be called instead whenever np.random.seed 
    is called in any module that is invoked during the execution of 
    the main script
    """
    print("Called with seed {}".format(seed))
    #or: import ipdb; ipdb.set_trace()
    return np.random.seed()

也许要使用模拟框架?

第二个问题涉及这样的场景:类B从库中的类A继承,我想使用类B的功能,但要覆盖它从类A使用的功能而不修改类A和B。 ,我应该使用模拟,但是我不确定开销,所以我写了以下内容:

#in library
class A():
    def __init__(self, name):
        self.name = name
    def work(self):
        print("{} working".format(self.name))

class B():
    def __init__(self):
        self.A = A("Machine")
    def run_task(self):
        self.A.work()

# in main script
# Cannot change classes A and B, so make a subclass C
import types
class C(B):
    def __init__(self, modified_work):
        super().__init__()
        self.A.work = types.MethodType(modified_work, self.A) #MethodType for self

b = B()
b.run_task()
modified_work = lambda self: print("{} working faster".format(self.name))
c = C(modified_work)
c.run_task()

输出为:

Machine working
Machine working faster

这是好风格吗?

1 个答案:

答案 0 :(得分:0)

这可能是您第二个问题的简单解决方案:

# lib.py
class A():
    def work(self):
        print('working')

class B():
    def __init__(self):
        self.a = A()
    def run(self):
        self.a.work()

然后在您的代码中:

import lib

class A(lib.A):
    def work(self):
        print('hardly working')

lib.A = A

b = lib.B()
b.run()

或者:

import lib

class AA(lib.A):
    def work(self):
        print('hardly working')

class BB(lib.B):
    def __init__(self):
        self.a = AA()

b = lib.B()
b.run()
b = BB()
b.run()