Python 扩展模块中无法创建实例

16 阅读2分钟

在Python扩展模块中创建实例时,确保你遵循了正确的步骤。在扩展模块中,通常需要定义一个初始化函数来初始化模块。在这个函数中,你可以注册扩展类型或其他必要的操作。确保你的初始化函数被正确调用,并且没有抛出异常。总之在扩展模块中经常会遇到各种的问题,具体可以参考我下面的方法。

a2.png

1、问题背景

问题描述:在使用 PyCXX 创建一个简单的 Python 扩展模块时,在 Python 中无法创建该模块的实例。错误信息为“TypeError: cannot create 'Kitty' instances”。

代码示例:

#include "CXX/Objects.hxx"
#include "CXX/Extensions.hxx"
#include <iostream>using namespace Py;
using namespace std;
​
class Kitty : public Py::PythonExtension<Kitty>
{
    public:
        Kitty()
        {
        }
​
        virtual ~Kitty()
        {
        }
​
        static void init_type(void)
        {
            behaviors().name("Kitty");
            behaviors().supportGetattr();
​
            add_varargs_method("Speak", &Kitty::Speak);
        }
​
        virtual Py::Object getattr( const char *name )
        {
            return getattr_methods( name );
        }
​
        Py::Object Speak( const Py::Tuple &args )
        {
            cout << "Meow!" << endl;
            return Py::None();
        }
};
​
class Cats : public ExtensionModule<Cats>
{
    public:
        Cats()
            : ExtensionModule<Cats>("Cats")
        {
            Kitty::init_type();
​
            initialize();
​
            Dict d(moduleDictionary());
            d["Kitty"] = Type((PyObject*)Kitty::type_object());
        }
​
        virtual ~Cats()
        {
        }
​
        Py::Object factory_Kitty( const Py::Tuple &rargs )
        {
            return Py::asObject( new Kitty );
        }
};
​
void init_Cats()
{
    static Cats* cats = new Cats;
}
​
​
int main(int argc, char* argv[])
{
    Py_Initialize();
​
    init_Cats();
​
    return Py_Main(argc, argv);
​
    return 0;
}

2、解决方案

答案1:

在代码中,缺少一个 factory_Kitty 方法,该方法用于创建并返回 Kitty 实例。添加 factory_Kitty 方法如下:

Py::Object factory_Kitty( const Py::Tuple &args )
{
    return Py::asObject( new Kitty );
}

完整的代码如下:

#include "CXX/Objects.hxx"
#include "CXX/Extensions.hxx"
#include <iostream>using namespace Py;
using namespace std;
​
class Kitty : public Py::PythonExtension<Kitty>
{
    public:
        Kitty()
        {
        }
​
        virtual ~Kitty()
        {
        }
​
        static void init_type(void)
        {
            behaviors().name("Kitty");
            behaviors().supportGetattr();
​
            add_varargs_method("Speak", &Kitty::Speak);
        }
​
        virtual Py::Object getattr( const char *name )
        {
            return getattr_methods( name );
        }
​
        Py::Object Speak( const Py::Tuple &args )
        {
            cout << "Meow!" << endl;
            return Py::None();
        }
};
​
class Cats : public ExtensionModule<Cats>
{
    public:
        Cats()
            : ExtensionModule<Cats>("Cats")
        {
            Kitty::init_type();
​
            initialize();
​
            Dict d(moduleDictionary());
            d["Kitty"] = Type((PyObject*)Kitty::type_object());
        }
​
        virtual ~Cats()
        {
        }
​
        Py::Object factory_Kitty( const Py::Tuple &args )
        {
            return Py::asObject( new Kitty );
        }
};
​
void init_Cats()
{
    static Cats* cats = new Cats;
}
​
​
int main(int argc, char* argv[])
{
    Py_Initialize();
​
    init_Cats();
​
    return Py_Main(argc, argv);
​
    return 0;
}

现在,您就可以在 Python 中创建 Kitty 实例了。

如果以上步骤都正确但仍然无法创建实例,你可以使用调试工具来检查代码并查找问题所在。使用打印语句、调试器或日志记录来跟踪程序的执行流程,并尝试找到问题的根源。

如果可以提供更具体的代码示例或描述问题的细节,我这里可以给出更详细的建议。