我有一个库,它返回一些半抽象对象的集合。
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()
问题是,将MyItem(和任何其他子类)传递给Provider的优雅和pythonic解决方案是什么?
我可以将其作为Provider(item1=MyItem)
传递,将其存储为self.item1
,然后将其实例化为self.item1()
而不是Item1()
,但这看起来很难看。另外,我会在客户端代码中调用可怕的长构造函数。
其他选项是覆盖模块级别的类,如mylib.Item1 = MyItem
,但这会导致许多意外且难以调试的问题。此外,可能有几个不同的提供程序类使用相同的项目基类,但需要来自客户端的不同子类。
也许某种形式的类注册表和工厂而不是实际的类?因此,Item1()会尝试根据某些上下文来确定要实例化的类,但我不确定它是如何工作的。
答案 0 :(得分: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])
答案 1 :(得分:0)
你会认为这很难看吗?
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)
答案 2 :(得分: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])