2016-10-03 125 views
0

我有一个“黑盒子”python模块,我想扩展。该模块提供class Foo类没有__init__函数,并且帮助函数FooMaker返回Foo类型的对象。扩展模块的常用策略:扩展黑盒python模块

class ExtendedFoo(blackbox.Foo): 
    def __init__(self, x): 
     super(ExtendedFoo, self).__init__(x) 

就不会在这里工作,因为,正如上面提到我需要依靠blackbox.FooMaker,而不是Foo__init__功能。

关于如何扩展模块blackbox的任何想法?

+1

在init中调用FooMaker? – idjaw

+3

使用组合而不是专门化 –

+0

您是否希望您的'__init__'在FooMaker执行任何初始化任务之前或之后运行? – MisterMiyagi

回答

0

原来的Foo类有一个setter函数,那么什么最终为我工作是

class ExtendedFoo(blackbox.Foo): 
    pass 

def ExtendedFooMaker(*args): 
    _efoo = ExtendedFoo() 
    _efoo.set(FooMaker(*args).get()) 
    return _efoo 
-1

除非模块做了一些严重的黑客攻击,否则您可以更换其成员。请注意,所有的参考和分配工作都在blackbox.名称上,而不是本地名称!

如果您希望您的新班级'__init__FooMaker内运行,只需继承并替换Foo即可。

import blackbox 
class ExtendedFoo(blackbox.Foo): 
    def __init__(self, x): 
     super(ExtendedFoo, self).__init__(x) 

blackbox.Foo = ExtendedFoo 

这样,FooMaker将实例的唯一ExtendedFoo类。

或者,您可以用您自己的版本替换FooMaker

import blackbox 
_bbfoomaker = blackbox.FooMaker # keep reference so we can use it later 
def SuperFooMaker(*fooargs, **fookwargs): 
    new_instance = _bbfoomaker(*fooargs, **fookwargs) 
    new_instance.whitebox = True # or whatever 

blackbox.FooMaker = SuperFooMaker 

的限制,二是,如果另一个模块做类似from blackbox import FooMaker,你的模块必须运行/导入。否则,其他模块仍然会看到原始工厂,类似于您仍然拥有的_bbfoomaker

+0

第一个选项不起作用,可能是因为黑盒模块在自己的命名空间中做了一些奇怪的事情。第二种选择只是创建一个'blackbox.Foo'的实例,而我真的想要一个新的名字带一个新的名字 –

+0

这个'blackbox'能以某种方式看到吗? – MisterMiyagi

+0

是的,“Foo”类是'lxml.etree._ElementTree','FooMaker'是'lxml.etree.parse' –

1

这应该做与您的解决方案,但有点短:

from blackbox import Foo, FooMaker 

class ExtendedFoo(Foo): 

    def __init__(self, *args, **kwargs): 
     self.set(FooMaker(*args, **kwargs).get())