为了简化 C++ 与 Python 的互操作,PyCXX设计了 Object 类,使用 C++ 封装了 Python 对象(PyObject*)。
整个库最核心的就是Object类,它的核心是封装了一个 PyObject* 指针,并管理其生命周期(引用计数)。
通过 C++ 的 RAII 机制,确保 Python 对象在 C++ 作用域内安全地创建和销毁。
PyCXX中的所有类型位于 Py 命名空间下:
| Py命名空间中的类型 |
功能 |
Py::Object |
PyCXX框架中的基类,它封装了一个 PyObject* 指针(p),并管理其生命周期(引用计数)。 通过 C++ 的 RAII(资源获取即初始化)机制,确保 Python 对象在 C++ 作用域内安全地创建和销毁。 |
Py::PythonClass<T> |
用于将一个 C++ 类型 (T) 封装为 Python 可识别的类对象,暴露 C++ 成员函数和属性给 Python |
Py::ExtensionModule<T> |
用来定义Python模块,在构造时将模块注册到 Python 解释器中。 |
Py::List |
C++实现的Python序列类,存储序列对象(如列表/元组) |
Py::Tuple |
C++实现的Python元组 |
Py::Dict |
C++实现的Python字典 |
Py::Callable |
使用C++封装的Python可调用对象 |
Py 命名空间下的函数:
| Py命名空间下的函数 |
|
void Py::_XINCREF( PyObject *op ); |
增加PyObject的引用计数。 |
void Py::_XDECREF( PyObject *op ); |
减少PyObject的引用计数,当引用计数减至0时,对象会被自动释放。这是CPython内部用于内存管理的核心机制。 |
bool operator==( const Object &o1, const Object &o2 );
|
Py::Object对象比较, 同时也实现了 !=, >=, <=, <, > |
1. Py::Object基类
在PyCXX中,所有类型的基类都是Py::Object派生类型,直接派生或者间接派生。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
namespace Py
{
class Object
{
private:
PyObject *p; // 通过组合 PyObject* 实现对 Python 对象的封装
protected:
void set( PyObject *pyob, bool owned = false ) // 设置 p
{
release(); // 先释放原先持有的 p
p = pyob;
if( !owned ) { Py::_XINCREF( p ); }
validate();
}
void release() // 释放 p
{
Py::_XDECREF( p );
p = NULL;
}
void validate(); // 于验证当前对象的类型是否与预期匹配
public:
// 构造函数: 根据 owned 决定是否增加 pyob 的引用计数。
// owned: Object对象是否拥有 pyob。
explicit Object( PyObject *pyob=Py::_None(), bool owned = false );
Object( const Object &ob );
Object &operator=( const Object &rhs ); // 调用 set( rhs.p );
Object &operator=( PyObject *rhsp ) // 防止自赋值
// 析构函数: pyob 引用计数减1,并 p = NULL。
virtual ~Object()
{
release();
}
PyObject *operator*() const; // 重载解引用,也就是返回 p
void increment_reference_count(); // 调用Py_INCREF宏增加对象引用计数
void decrement_reference_count(); // 特殊处理引用计数减少,当引用计数为1时抛出异常(防止对象自我销毁),正常情况调用Py_DECREF宏减少引用计数
PyObject *ptr() const; // 直接返回 PyObject 对象指针
/*
* 判断给定的Python对象是否可用于当前类,
* 例如派生类型Py::Tuple重写了该函数,当Python对象为Py::Tuple时返回true
*/
virtual bool accepts( PyObject * ) const;
Py_ssize_t reference_count() const; // 返回当前对象的引用计数
Type type() const; // 返回当前Python对象对应的类型对象,用于获取Python对象的类型信息等
String str() const; // 获取Python对象的字符串表示(Py::string),例如: 字典 {'a':1} -> "{'a': 1}"
std::string as_string() const; // 调用了str(),但是强制转换为std::string
List dir() const; // 获取Python对象的属性名称列表并封装为C++的List对象返回
bool hasAttr( const std::string &s ) const; // 检查Python对象是否包含指定属性
Object getAttr( const std::string &s ) const; // 获取属性的值
void setAttr( const std::string &s, const Object &value );
void delAttr( const std::string &s );
// 函数调用,function_name就是函数名
Object callMemberFunction( const std::string &function_name ) const; // 调用无参函数
Object callMemberFunction( const std::string &function_name, const Tuple &args ) const; // 调用带有可变参的函数
Object callMemberFunction( const std::string &function_name, const Tuple &args, const Dict &kw ) const; // 调用带有可变参和关键字参数的函数
Object getItem( const Object &key ) const; // 键值访问,用于Python容器类型(如字典/列表)
Py_hash_t hashValue() const; // 计算对象哈希值
bool is( PyObject *pother ) const; // return p == pother;
bool is( const Object &other ) const; // return p == other.p;
// 检测 p 是否为某个类型
bool isNull() const;
bool isNone() const;
bool isCallable() const;
bool isDict() const;
bool isList() const;
bool isMapping() const;
bool isNumeric() const;
bool isSequence() const;
bool isTrue() const;
bool isTuple() const;
bool isString() const;
bool isBytes() const;
bool isBoolean() const;
bool isType( const Type &t ) const; // 当前对象的类型是否与参数t的类型完全相同
void delItem( const Object &key ); // 删除 p 中的键值对
};
}
|