Python:如何编写补丁(swap)类

时间:2015-09-28 03:27:51

标签: python

假设我在模块cell.selectionStyle = UITableViewCellSelectionStyleNone; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // Write code for create your cell and properties regarding that cell //add this line cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; }

中有以下两个类
a
模块class Real(object): ... def print_stuff(self): print 'real' class Fake(Real): def print_stff(self): print 'fake' 中的

使用b

Real

如何修补补丁,以便from a import Real Real().print_stuff() 导入b时实际与Real交换?

我试图在初始化脚本中这样做,但它不起作用。

Fake

我的目的是在开发模式下使用Fake类。

2 个答案:

答案 0 :(得分:3)

您可以使用patch模块中的mock。这是一个例子:

with patch('yourpackage.b.Real') as fake_real:
    fake_real.return_value = Fake()
    foo = b.someClass()
    foo.somemethod()

答案 1 :(得分:2)

问题是当你这样做时 -

from a import Real, Fake

您基本上将这两个类导入initialize脚本的命名空间,并在Real脚本的命名空间中创建Fakeinitialize个名称。然后,您将Real脚本中的名称initialize指向Fake,但这不会改变实际a模块中的任何内容。

如果initialize脚本是原始程序开始时运行的另一个.py模块/脚本,那么您可以使用以下内容 -

if env == 'dev':
    import a
    a.Real = a.Fake

请注意,执行上述行后,只要您在a.Real模块中使用FakeReal类就会引用a

虽然我建议更好的方法是在a模块中执行此操作,但可以检查该模块中的env,如 -

if <someothermodule>.env == 'dev':
    Real = Fake

正如评论中所提到的那样 -

  

还没有导入初始化脚本的命名空间吗?导入模块和类之间的区别是什么?

问题在于,当您使用from a import class仅导入类时,您实际执行的操作是在模块命名空间中创建该变量class(在导入它的模块中),更改该变量指向该模块命名空间中的新内容不会影响其原始模块对象中的原始类,它仅在其更改的模块中受到影响。

但是当您执行import a时,您只是导入模块a(导入模块对象时也会缓存在sys.modules字典中,因此任何其他导入到a来自任何其他模块的1}}将从sys.modules获得此缓存版本(另请注意,from a import something还在内部导入a并将其缓存在sys.modules中,但让没有进入这些细节,因为我认为这里没有必要。)

然后当你执行a.Real = <something>时,你正在将Real模块对象的a属性(指向该类)更改为其他内容,这会使{{1}变异直接模块,因此当模块a从其他模块导入时,也会反映出更改。