【问题标题】:Patching built-in method or class修补内置方法或类
【发布时间】:2018-07-13 10:07:25
【问题描述】:

我想在代码中找到调用 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类和B类的情况下覆盖它从A类使用的函数。可能,我应该使用mocking,但是我不确定开销,所以我写了以下内容:

#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

这样的风格好吗?

【问题讨论】:

    标签: python mocking built-in


    【解决方案1】:

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

    # 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()
    

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2020-06-17
      • 2018-11-10
      • 2015-11-22
      • 1970-01-01
      • 2016-10-10
      • 2017-05-24
      • 2011-12-15
      • 2011-07-26
      相关资源
      最近更新 更多