【问题标题】:How to implement CRTP functionality in python?如何在 python 中实现 CRTP 功能?
【发布时间】:2018-01-02 04:43:24
【问题描述】:

我想从 python 中的基类访问派生类的成员(变量)。在c++ 中,我可以为此使用 CRTP 设计模式。例如,在 c++ 中,我会这样做:

#include <iostream>


template <class derived>
class Base {

    public:
        void get_value()
            {
            double value = static_cast<derived *> (this) -> myvalue_;
            std::cout<< "This is the derived value: " << value << std::endl;
        }

};
class derived:public Base<derived>{

    public:

        double myvalue_;

        derived(double &_myvalue)
            {
                myvalue_ = _myvalue;
            }
};

用法:

int main(){

    double some_value=5.0;
    derived myclass(some_value);
    myclass.get_value();
    // This prints on screen "This is the derived value: 5"
};

有什么方法可以在 python 中实现这个功能?

我想要做的是拥有一个单一基类,它具有一组基于派生类成员变量的通用函数。我想避免在所有派生类中重写/重复这组通用函数。

【问题讨论】:

    标签: python c++ crtp


    【解决方案1】:

    我不确定它是否是您要查找的内容,但只要subclass 具有属性,即使它未在baseclass 中定义,它也可以通过实例访问它。

    class Base(object):
        def getValue(self):
            print(self.myvalue)
    
    
    
    class Derived(Base):
        def __init__(self, myvalue):
            self.myvalue = myvalue
    
    
    
    val = 3
    derived = Derived(3)
    derived.getValue()
    #>3
    

    【讨论】:

      【解决方案2】:

      也许你应该退后一步问一下,为什么我们还要在 C++ 中使用 CRTP。使用 CRTP 的原因是我们可能希望在编译时多态地使用一个类,或者省略虚函数调用开销。

      现在 Python 没有“编译时间”,因为它不是静态类型的,所以所有函数调用本质上都是虚拟的。因此,您将获得与 CRTP 相同的行为,只是使用常规继承。

      class Base(object):
          def get_value(self):
              print("This is the derived value:", self.value)
      
      class Derived(Base):
          def __init__(self, value):
              self.value = value
      
      d = Derived(5)
      d.get_value() # prints "This is the derived value: 5"
      

      Live example

      另一方面,如果您希望 CRTP 与 Python3 typing 系统进行交互,那么您可能需要查看以下问题:Python 3 type hint for a factory method on a base class returning a child class instance

      【讨论】:

      • 在 OP 的情况下,'self.value' 是在 'Derived' 中定义的,所以 Base 类不知道它。
      • 感谢您抽出宝贵时间进行补充说明。我需要 self.value 在 Derived 类上,而不是在 Base 类上。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多