假设有两个类Base1
,Base2
继承自公共基类Base
。此外,还有一些与ff
一起使用的函数Base
。
在C ++中,可以定义将从Derived
或Base1
继承的模板类Base2
,创建该类型的对象并将其传递给ff
:< / p>
// Given
struct Base1 : Base { };
struct Base2 : Base { };
void ff(const Base& base) { }
// you can do...
template < typename BB >
struct Derived : public BB { /* implement here what is common to both Derived1 and Derived2 */ };
struct Derived1 : public Derived<Base1> { /* implement here what is specific to Derived1 but not Derived2 */ };
struct Derived2 : public Derived<Base2> { /* implement here what is specific to Derived2 but not Derived1 */ };
// ... and live your life in peace with:
Derived1 d1;
Derived2 d2;
ff(d1);
ff(d2);
问题是我如何在Python3.6中实现相同的架构?
答案 0 :(得分:0)
下面的代码只是为了表明它可以在Python中使用,但恕我直言,它不是真正的Pythonic,因为它只是模仿C ++模板。
>>> class Base:
pass
>>> class Base1(Base):
pass
>>> class Base2(Base):
pass
>>> def templated(base): # a Python decorator to mimic the C++ templating engine
def outer(clazz):
class Inner(base):
_base = base # a class attribute that will be tested later
return Inner
return outer
>>> class Derived:
pass # implement what is common to both Derived1 and Derived2
>>> @templated(Base1)
class Derived1:
pass # implement what is specific to Derived1
>>> Derived1._base # to prove that it extends Derived<Base1> (C++ like syntax)
<class '__main__.Base1'>
>>> Derived1.__mro__ # base classes
(<class '__main__.templated.<locals>.outer.<locals>.Inner'>, <class '__main__.Base1'>,
<class '__main__.Base'>, <class 'object'>)
>>>
但是在任何真实的例子中,肯定会有一种更简单的方式......
答案 1 :(得分:0)
我为自己编写了一个玩具库,以便与元类一起玩。您可以使用pip install type_templating
from PyPI来获得它。源自one of its tests。
from type_templating import Template, TemplateParameter
class Base: pass
class Base1(Base): pass
class Base2(Base): pass
BB = TemplateParameter('BB')
# Derived is a template taking one argument
class Derived(BB, metaclass=Template[BB]):
# implement here what is common to both Derived1
# and Derived2. The template argument is accessible as
# `self.__args[BB]`
pass
class Derived1(Derived[Base1]): pass
class Derived2(Derived[Base2]): pass
与内置typing.Generic
不同,这不会删除模板参数信息,并允许传递值和类型。