Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 参数化继承的元类_C++_Python_Templates_Metaprogramming_Metaclass - Fatal编程技术网

C++ 参数化继承的元类

C++ 参数化继承的元类,c++,python,templates,metaprogramming,metaclass,C++,Python,Templates,Metaprogramming,Metaclass,我读了一些关于Python元类的教程。我以前从未使用过一个,但我需要一个相对简单的工具,而且所有教程似乎都面向更复杂的用例。我基本上想创建一个模板类,它有一些预先指定的主体,但将其基类作为参数。由于我是从C++/D模板中得到这个想法的,下面是一个我想在C++中编写的代码的示例: template<class T> class Foo : T { void fun() {} } 模板 类别Foo:T{ void fun(){} } 虽然可以使用元类来完

我读了一些关于Python元类的教程。我以前从未使用过一个,但我需要一个相对简单的工具,而且所有教程似乎都面向更复杂的用例。我基本上想创建一个模板类,它有一些预先指定的主体,但将其基类作为参数。由于我是从C++/D模板中得到这个想法的,下面是一个我想在C++中编写的代码的示例:

template<class T>
    class Foo : T {
        void fun() {}
    }
模板
类别Foo:T{
void fun(){}
}

虽然可以使用元类来完成,但是您可以在没有元类的情况下做任何事情,因为在Python中类本身就是对象。令人惊讶的是,基本上只需要一个几乎一对一的C++代码翻译。由于这一点,它不仅相对简单,而且在Python2和Python3中都可以不经修改地工作

def template(class_T):
    """Factory function to create subclasses of class_T."""

    class Foo(class_T):
        def fun(self):
            print('%s.fun()' % self.__class__.__name__)

    Foo.__name__ += '_' + class_T.__name__  # rename the subclass to reflect its heritage
    return Foo

class Base1:
    def bar(self):
        print('Base1.bar()')

class Base2:
    def bar(self):
        print('Base2.bar()')

Foo_Base1 = template(Base1)
print('Foo_Base1 base classes: {}'.format(Foo_Base1.__bases__))

Foo_Base2 = template(Base2)
print('Foo_Base2 base classes: {}'.format(Foo_Base2.__bases__))

subclass1 = Foo_Base1()
subclass1.fun()
subclass1.bar()
subclass2 = Foo_Base2()
subclass2.fun()
subclass2.bar()
输出:

Foo_Base1基类:(,)
Foo_Base2基类:(,)
Foo_Base1.fun()
Base1.bar()
Foo_Base2.fun()
Base2.bar()
(以非想象的方式命名)
template()
函数中的代码是通常称为工厂模式或工厂模式实现的示例。因此,顺便说一句,你可能会发现这个问题很有启发性


编辑:添加代码,为返回的每个子类创建不同的类名,这是受@的洞察(在现已删除的注释中)的启发,即调试时,如果生成的类始终具有相同的名称,则可能会产生混淆。

这在Python中没有意义,因为它没有模板。我对C++中参数化模板的理解(这是相当模糊的,因为我已经看了很多年),它的作用就像类工厂,可以创建一个子类,它可以提供任何附加的方法或属性。 在Python中,您可以使用一个工厂函数来实现这一点,该工厂函数接受一个类并在运行时返回一个新类:

In [1]: def subclassFactory(cls):
   ...:     class Foo(cls):
   ...:         def fun(self):
   ...:             return "this is fun"
   ...:     return Foo
   ...: 

In [2]: class A(object):
   ...:     pass
   ...: 

In [5]: C = subclassFactory(A)

In [6]: C
Out[6]: <class '__main__.Foo'>
In [7]: c = C()
In [9]: c.fun()
Out[9]: 'this is fun'
In [10]: isinstance(c, A)
Out[10]: True
[1]中的
:def子类工厂(cls):
…:类别Foo(cls):
…:def fun(self):
…:返回“这很有趣”
…:返回Foo
...: 
在[2]中:A类(对象):
…:通过
...: 
在[5]中:C=子类工厂(A)
在[6]:C中
出[6]:
在[7]中:c=c()
在[9]:c.fun()
出[9]:“这很有趣”
在[10]中:isinstance(c,A)
Out[10]:对

太棒了,我想元类对于这么简单的东西来说太过分了。事后看来,这个解决方案非常有意义,因为类型是Python中的第一类对象,可以在运行时创建类。我想,我还没有习惯于用动态的语言思维来自己去提高它。模板是C++中的元语言,是一种强类型语言。在弱类型的Python中,类也是对象,正如您所指出的,通常不需要这样做——但当您这样做时,您不仅限于模板参数,还可以做一些惊人的事情。Python是强类型的,您不能像在Javascript等弱类型语言中那样在Python中添加字符串和整数。顺便说一句,Python也是动态类型的。@Lie Ryan:你说得很对——我使用了错误的术语,把强/弱与静态/动态类型混淆了。谢谢你的更正。