代码之家  ›  专栏  ›  技术社区  ›  Daniel Kluev

将子类传递到导入的库

  •  0
  • Daniel Kluev  · 技术社区  · 15 年前

    我有一个库,它返回一些半抽象对象的集合。

    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的优雅的、蟒蛇式的解决方案是什么?

    我可以把它当作 Provider(item1=MyItem) ,存储为 self.item1 ,然后将其实例化为 self.item1() 而不是 Item1() 但这似乎很短暂。另外,我将在整个客户机代码中进行可怕的、长的构造函数调用。

    另一种选择是重写模块级的类,比如 mylib.Item1 = MyItem 但这可能会导致许多意外的和难以调试的问题。此外,可能有几个不同的提供程序类使用相同的项基类,但需要来自客户端的不同子类。

    也许是某种形式的类注册中心和工厂而不是实际的类?因此item1()将尝试根据一些上下文来确定要实例化哪个类,但我不确定这将如何工作。

    3 回复  |  直到 15 年前
        1
  •  1
  •   John La Rooy    15 年前

    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])
    
        2
  •  0
  •   Jeff Mercado    15 年前

    你认为这很容易吗?

    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)
    
        3
  •  0
  •   John La Rooy    15 年前

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