2010-08-18 34 views
0

我有一個庫,它返回一些半抽象對象的集合。將子類傳遞給導入的庫

class Item1(object): 
    pass 
class Item2(object): 
    pass 
class Collection1(object): 
    pass 

class Provider(object): 
    def retrieve_collection(self): 
     col = Collection1() 
     col.add(Item1()) 
     col.add(Item2()) 
     return col 

它只是填充對象的屬性,而這些項目/集合類意在主叫用戶代碼被繼承。

所以會有一些腳本

from mylib import Provider, Item1 
class MyItem(Item1): 
    pass 
provider = Provider() 
col = provider.retrieve_collection() 

,問題是,什麼是優雅和Python的解決方案,MyItem(以及任何其他子類)傳遞給供應商?

我可以把它作爲Provider(item1=MyItem),將其存儲爲self.item1,然後實例作爲self.item1(),而不是Item1(),但這似乎是fugly。另外,我會在客戶端代碼中調用可怕的長整型構造函數。

其他選項將覆蓋在模塊級班,像mylib.Item1 = MyItem,但是這可能會導致許多意想不到的和難以調試的問題。此外,可能有幾個不同的提供者類使用相同的項目基類,但需要來自客戶端的不同子類。

也許某種形式的類註冊表和工廠而不是實際的類?因此,Item1()會嘗試根據某個上下文來確定要實例化哪個類,但我不確定這是如何工作的。

回答

0

你作爲的fugly考慮呢?

class Provider(object): 
    def retrieve_collection(self, type0=Item1, type1=Item2): 
     col = Collection1() 
     col.add(type0()) 
     col.add(type1()) 
     return col 


col = provider.retrieve_collection(MyItem) 
+0

嗯,這是相同的提供商實例設置它們,除了在我的情況會更糟糕,由於這樣的事實,供應商的方法稱爲所有的代碼,而實例化只發生了幾次。 – 2010-08-18 08:27:23

1

mylib.py

class Item1(object): 
    def __repr__(self): 
     return "Base Item1" 
class Item2(object): 
    def __repr__(self): 
     return "Base Item2" 
class Collection1(set): 
    pass 

class Provider(object): 
    Item1=Item1 
    Item2=Item2 
    def retrieve_collection(self): 
     col = Collection1() 
     col.add(self.Item1()) 
     col.add(self.Item2()) 
     return col 

from mylib import Provider 

class MyProvider(Provider): 
    class Item1(Provider.Item1): 
     def __repr__(self): 
      return "Subclass Item1" 

p=Provider() 
print p.retrieve_collection() 

p=MyProvider() 
print p.retrieve_collection() 

輸出:

Collection1([Base Item2, Base Item1]) 
Collection1([Base Item2, Subclass Item1]) 
0

mylib.py

class Item1(object): 
    def __repr__(self): 
     return "Base Item1" 
class Item2(object): 
    def __repr__(self): 
     return "Base Item2" 
class Collection1(set): 
    pass 

class Provider(object): 
    Item1=Item1 
    Item2=Item2 
    def retrieve_collection(self): 
     col = Collection1() 
     col.add(self.Item1()) 
     col.add(self.Item2()) 
     return col 

def ProviderFactory(**kw): 
    return type('Provider', (Provider,)+Provider.__bases__, kw) 

from mylib import ProviderFactory, Item1 

class Item1(Item1): 
    def __repr__(self): 
     return "Subclass Item1" 

MyProvider=ProviderFactory(Item1=Item1) 


p=MyProvider() 
print p.retrieve_collection() 

輸出:

Collection1([Base Item2, Subclass Item1])