You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Boost.Python封装C++类时触发TypeError:__init__应返回None而非'NoneType'

解决Boost.Python中__init__() should return None, not 'NoneType'错误

问题分析

你碰到的这个错误是Boost.Python开发里非常典型的版本不匹配问题:编译扩展库时链接的Python版本,和运行代码时使用的Python版本不一致。从你的CMake输出能看到,编译时用的是Python 2.7(found version "2.7.16"),但你运行Python代码时大概率用了Python 3环境,这种版本错位会导致底层类型系统不兼容,从而抛出这个看起来有点奇怪的返回值错误。

另外,你的CMake脚本在版本检测逻辑上有冗余,也容易引发版本匹配问题,这也是需要调整的点。

解决方案

1. 先确认编译与运行的Python版本一致

先检查你运行Python代码时用的是哪个版本:

# 查看当前默认Python路径
which python
# 或者检查Python3的路径
which python3

如果运行时用的是Python3,那必须修改CMake脚本,强制指定用Python3编译扩展库。

2. 修复CMake脚本的版本检测逻辑

现有脚本的跨平台版本检测过于繁琐,容易出错,我们可以简化并明确指定Python版本,比如强制使用Python3:

cmake_minimum_required(VERSION 3.13)
project(p1)
set(CMAKE_CXX_STANDARD 11)

# 明确指定优先查找Python3
set(Python_ADDITIONAL_VERSIONS 3.6 3.7 3.8 3.9)
find_package(PythonInterp 3 REQUIRED)
find_package(PythonLibs 3 REQUIRED)

# 匹配对应版本的Boost.Python组件
if(UNIX AND NOT APPLE)
    find_package(Boost COMPONENTS python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR} REQUIRED)
else()
    # macOS下Boost的Python组件命名通常是python3x格式,比如python37
    find_package(Boost COMPONENTS python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR} REQUIRED)
endif()

# 打印检测信息,确认版本匹配
message(STATUS "PYTHON_LIBRARIES = ${PYTHON_LIBRARIES}")
message(STATUS "PYTHON_EXECUTABLE = ${PYTHON_EXECUTABLE}")
message(STATUS "PYTHON_INCLUDE_DIRS = ${PYTHON_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARIES = ${Boost_LIBRARIES}")

include_directories(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
add_library(pylib SHARED pylib.cpp)
target_link_libraries(pylib ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})

# 设置库的后缀和前缀,符合Python扩展命名规范
set_target_properties(pylib PROPERTIES SUFFIX .so)
set_target_properties(pylib PROPERTIES PREFIX "")

3. 清理旧编译文件并重新构建

删除之前的编译目录,避免残留旧版本的编译产物:

rm -rf cmake-build-debug
mkdir cmake-build-debug && cd cmake-build-debug
cmake .. -DCMAKE_BUILD_TYPE=Debug
make

4. 验证版本一致性

编译完成后,在运行Python代码的环境里先确认版本:

import sys
print(sys.version)

确保这个版本和CMake输出里的PYTHON_EXECUTABLE版本完全一致。

额外优化建议

建议移除C++头文件里的using namespace std;,它可能和Boost.Python的命名空间产生冲突,修改后的Bonjour.hpp如下:

#include <iostream>
#include <string>

class Bonjour {
    std::string m_msg;
public:
    Bonjour(std::string msg):m_msg(msg) { }
    void greet() { std::cout << m_msg << std::endl; }
    void check_func() { std::cout<<"Hello! I am working"; }
    void set_msg(std::string msg) { this->m_msg = msg; }
    std::string get_msg() const { return m_msg; }
};

验证修复

重新编译后,运行你的Python代码:

from pylib import Bonjour
b = Bonjour("He")
b.greet()  # 应输出"He"
print(b.msg)  # 应输出"He"
b.msg = "Hello World"
b.greet()  # 应输出"Hello World"

内容的提问来源于stack exchange,提问作者Prakhar Agarwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:40:22