2010-08-18 57 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])