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