EveryThing to EveryThing 类型转换兼容层
项目概述
本项目实现了一个Python类型转换兼容层,支持所有Python标准数据类型之间的双向转换功能。该兼容层在不修改Python内置函数原有接口和使用方式的前提下,扩展了其转换能力,实现了不同标准数据类型间的无缝转换。
支持的转换类型
-
基本类型:int、float、str、bool、NoneType
-
容器类型:list、tuple、dict、set
-
字节类型:bytes
-
第三方库类型(可选,需安装对应库):
-
NumPy 数组 (
numpy.ndarray) -
CuPy 数组 (
cupy.ndarray) -
SciPy 稀疏矩阵 (
scipy.sparse.*) -
Pandas 类型 (
pandas.DataFrame,pandas.Series) -
PyTorch 张量 (
torch.Tensor) -
xarray 类型 (
xarray.DataArray,xarray.Dataset) -
JAX 数组 (
jax.numpy.ndarray) -
TensorFlow 张量 (
tensorflow.Tensor)
转换规则
1. 转换为 list
-
list:保持不变
-
None:返回空列表
[] -
str/bytes:转换为字符/字节列表
-
dict:转换为键值对元组列表
-
int/float/bool:转换为单元素列表
-
tuple/set:转换为列表
-
其他:尝试使用原始 list() 函数
2. 转换为 str
-
str:保持不变
-
None:返回空字符串
"" -
bool:转换为小写字符串 (“true”/“false”)
-
int/float/list/tuple/dict/set:使用原始 str() 函数
-
其他:尝试使用原始 str() 函数
3. 转换为 int
-
int:保持不变
-
None:返回 0
-
bool:转换为 1/0
-
float:截断小数部分
-
str:尝试转换为整数
-
空容器:返回 0
-
单元素容器:转换容器内元素
-
多元素容器:抛出 TypeError
-
其他:尝试使用原始 int() 函数
4. 转换为 float
-
float:保持不变
-
None:返回 0.0
-
bool:转换为 1.0/0.0
-
int:转换为浮点数
-
str:尝试转换为浮点数
-
空容器:返回 0.0
-
单元素容器:转换容器内元素
-
多元素容器:抛出 TypeError
-
其他:尝试使用原始 float() 函数
5. 转换为 dict
-
dict:保持不变
-
None:返回空字典
{} -
list/tuple:尝试转换为字典,失败则转换为索引字典
-
str/int/float/bool/set:转换为
{"value": 值} -
其他:尝试使用原始 dict() 函数
6. 转换为 set
-
set:保持不变
-
None:返回空集合
set() -
str/bytes:转换为字符/字节集合
-
int/float/bool:转换为单元素集合
-
list/tuple/dict:转换为集合
-
其他:尝试使用原始 set() 函数
7. 转换为 tuple
-
tuple:保持不变
-
None:返回空元组
() -
str/bytes:转换为字符/字节元组
-
int/float/bool:转换为单元素元组
-
list/set/dict:转换为元组
-
其他:尝试使用原始 tuple() 函数
8. 第三方库类型转换
NumPy 数组
-
转换为 list:转换为嵌套列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅标量数组
-
转换为 dict:1D 数组转换为索引字典,ND 数组转换为包含 shape、dtype、data 的字典
-
转换为 set:仅 1D 数组
-
转换为 tuple:转换为嵌套元组
CuPy 数组
-
转换为 list:转换为嵌套列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅标量数组
-
转换为 dict:1D 数组转换为索引字典,ND 数组转换为包含 shape、dtype、data 的字典
-
转换为 set:仅 1D 数组
-
转换为 tuple:转换为嵌套元组
SciPy 稀疏矩阵
-
转换为 list:转换为密集数组列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅单元素矩阵
-
转换为 dict:1D 矩阵转换为索引字典,ND 矩阵转换为包含 shape、dtype、data 的字典
-
转换为 set:仅 1D 矩阵
-
转换为 tuple:转换为嵌套元组
Pandas DataFrame
-
转换为 list:包含列名的嵌套列表
-
转换为 str:转换为字典字符串
-
转换为 int/float:仅单元素 DataFrame
-
转换为 dict:转换为列名:列表字典
-
转换为 set:不支持
-
转换为 tuple:包含列名的嵌套元组
Pandas Series
-
转换为 list:转换为值列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅单元素 Series
-
转换为 dict:转换为索引:值字典
-
转换为 set:转换为值集合
-
转换为 tuple:转换为值元组
PyTorch Tensor
-
转换为 list:转换为嵌套列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅标量张量
-
转换为 dict:1D 张量转换为索引字典,ND 张量转换为包含 shape、data 的字典
-
转换为 set:仅 1D 张量
-
转换为 tuple:转换为嵌套元组
xarray DataArray
-
转换为 list:转换为嵌套列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅标量 DataArray
-
转换为 dict:包含 shape、dtype、data、dims、coords 的字典
-
转换为 set:仅 1D DataArray
-
转换为 tuple:转换为嵌套元组
xarray Dataset
-
转换为 list:包含变量字典的列表
-
转换为 str:转换为字典字符串
-
转换为 int/float:不支持
-
转换为 dict:变量名:变量信息字典
-
转换为 set:不支持
-
转换为 tuple:包含变量字典的元组
JAX 数组
-
转换为 list:转换为嵌套列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅标量数组
-
转换为 dict:1D 数组转换为索引字典,ND 数组转换为包含 shape、dtype、data 的字典
-
转换为 set:仅 1D 数组
-
转换为 tuple:转换为嵌套元组
TensorFlow Tensor
-
转换为 list:转换为嵌套列表
-
转换为 str:转换为列表字符串
-
转换为 int/float:仅标量张量
-
转换为 dict:1D 张量转换为索引字典,ND 张量转换为包含 shape、data 的字典
-
转换为 set:仅 1D 张量
-
转换为 tuple:转换为嵌套元组
使用示例
方法一:直接使用 e2e_* 函数
from e2e_type_converter import (
e2e_list, e2e_str, e2e_int, e2e_float, e2e_dict, e2e_set, e2e_tuple
)
# 示例 1:基本类型转换
print(e2e_list(123)) # 输出: [123]
print(e2e_str(None)) # 输出: ""
print(e2e_int("123")) # 输出: 123
print(e2e_float(True)) # 输出: 1.0
# 示例 2:容器类型转换
print(e2e_list({"a": 1, "b": 2})) # 输出: [("a", 1), ("b", 2)]
print(e2e_dict([1, 2, 3])) # 输出: {0: 1, 1: 2, 2: 3}
print(e2e_set("hello")) # 输出: {'h', 'e', 'l', 'o'}
# 示例 3:双向转换
print(e2e_list(e2e_tuple([1, 2, 3]))) # 输出: [1, 2, 3]
print(e2e_dict(e2e_list({"a": 1, "b": 2}))) # 输出: {"a": 1, "b": 2}
方法二:使用 TypeConverter 类
from e2e_type_converter import TypeConverter
# 示例
print(TypeConverter.to_list(123)) # 输出: [123]
print(TypeConverter.to_str(None)) # 输出: ""
print(TypeConverter.to_int("123")) # 输出: 123
方法三:重命名为内置函数名使用
from e2e_type_converter import (
e2e_list, e2e_str, e2e_int, e2e_float, e2e_dict, e2e_set, e2e_tuple
)
# 重命名以便使用
list = e2e_list
str = e2e_str
int = e2e_int
float = e2e_float
dict = e2e_dict
set = e2e_set
tuple = e2e_tuple
# 现在可以像使用内置函数一样使用
print(list(123)) # 输出: [123]
print(str(None)) # 输出: ""
print(int("123")) # 输出: 123
方法四:第三方库类型转换示例
from e2e_type_converter import e2e_list, e2e_dict, e2e_tuple
# NumPy 数组转换示例
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(e2e_list(arr)) # 输出: [[1, 2, 3], [4, 5, 6]]
print(e2e_dict(arr)) # 输出: {"shape": (2, 3), "dtype": "int32", "data": [[1, 2, 3], [4, 5, 6]]}
print(e2e_tuple(arr)) # 输出: ((1, 2, 3), (4, 5, 6))
# SciPy 稀疏矩阵转换示例
import scipy.sparse
sparse_mat = scipy.sparse.csr_matrix([[1, 0, 0], [0, 2, 0], [0, 0, 3]])
print(e2e_list(sparse_mat)) # 输出: [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
方法五:第三方库类型互转示例
from e2e_type_converter import TypeConverter
# NumPy 到 xarray 的转换
import numpy as np
numpy_arr = np.array([[1, 2, 3], [4, 5, 6]])
xarray_da = TypeConverter.numpy_to_xarray(numpy_arr)
print(xarray_da) # 输出 xarray DataArray
# xarray 到 NumPy 的转换
converted_back = TypeConverter.xarray_to_numpy(xarray_da)
print(converted_back) # 输出 numpy 数组
# 通用转换方法
import torch
# NumPy 到 PyTorch 的转换
torch_tensor = TypeConverter.convert(numpy_arr, 'torch')
print(torch_tensor) # 输出 PyTorch Tensor
# PyTorch 到 pandas 的转换(通过通用方法)
pandas_df = TypeConverter.convert(torch_tensor, 'pandas')
print(pandas_df) # 输出 pandas DataFrame
# 支持的转换方向
# 'numpy' <-> 'cupy' <-> 'scipy' <-> 'pandas' <-> 'torch' <-> 'xarray' <-> 'jax' <-> 'tensorflow'
注意事项
-
类型安全:对于不支持直接转换的类型组合,会抛出明确的 TypeError 或 ValueError 异常。
-
边界情况:
-
None 值会转换为对应类型的"空"值(如 、“”、0 等)
-
布尔值会被转换为对应类型的逻辑值(如 int(True) → 1)
- 性能优化:
-
类型检查顺序已优化,常见类型的检查优先级更高
-
对于容器类型的单元素转换,会递归处理内部元素
- 兼容性:
-
不直接修改内置函数,而是通过导入使用
-
保留了原始内置函数的行为,仅在其基础上扩展
- 限制:
-
对于多元素容器转换为数值类型(int/float),会抛出 TypeError
-
对于不可哈希类型,不支持缓存机制
- 第三方库支持:
-
第三方库支持采用懒加载方式,仅在实际使用时检测库是否安装
-
对于 NumPy/CuPy 数组,仅支持标量数组转换为 int/float
-
对于 NumPy/CuPy 数组和 SciPy 稀疏矩阵,仅支持 1D 类型转换为 set
-
对于多维数组/矩阵,转换为 dict 时会包含 shape、dtype 和 data 信息
单元测试
项目包含完整的单元测试,覆盖所有标准类型之间的转换场景:
python test_e2e_type_converter.py
项目结构
everything2everything/
├── e2e_type_converter/ # 包目录
│ ├── __init__.py # 模块导出和版本信息
│ └── core.py # 核心实现文件
├── setup.py # 包配置和依赖项
├── README.md # 文档说明
├── test_e2e_type_converter.py # 标准类型单元测试
└── test_third_party_types.py # 第三方库类型单元测试
总结
本类型转换兼容层提供了一种简洁、灵活的方式来处理Python中的类型转换问题,特别是在处理不同类型数据交互的场景中。通过扩展内置转换函数的能力,它使得类型转换更加直观和符合开发者的直觉预期,同时保持了与Python原生语法的兼容性。
项目空降
John-is-playing/everything2everything: A Python library that can convert any data type to any other data type
everything2everything - 全能类型转换兼容层