Skip to main content
 首页 » 编程设计

python之如何在 Python 中执行 C 风格类型转换

2025年05月04日26kevingrace

假设我有以下 np.uint8 数组:

In [9]: a = np.array([0x34, 0xF3, 0x87, 0x42]).astype(np.uint8) 
In [10]: a 
Out[10]: array([0x34, 0xf3, 0x87, 0x42], dtype=uint8) 

现在,当我转换为 np.uint16 时,我得到以下信息:

In [11]: b = a.astype(np.uint16) 
In [12]: b 
Out[12]: array([0x34, 0xf3, 0x87, 0x42], dtype=uint16) 

这是预期会发生的事情,但我想要别的东西。 例如,在 C 中,当您拥有类型为 uint8 (unsigned char) 的相同数组并且您想要访问它时,就好像它是一个包含 的数组一样uint16 (unsigned short) 元素:

unsigned char a[] = {0x34, 0xF3, 0x87, 0x42}; 
unsigned short* b = (unsigned short*)a; 

这将给我,正如 C 所期望的那样:

0x34 0xF3 0x87 0x42  // for a 
0xF334    0x4287     // for b, little or big endian, for me doesn't matter 

现在我的问题是,如何在 Python 中执行此类操作? (甚至可以在不创建新数组的情况下从一种类型转换为另一种类型吗?)

我可以像这样通过位移并将两个字节加在一起来创建一个新数组:

#! /usr/bin/python3 
 
import numpy as np 
 
np.set_printoptions(formatter={'int':hex}) 
 
# I assume, a has the len 2*n  and b has the len n (for conversion from 2*n Bytes in n 2Bytes) 
a = np.array([0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93]).astype(np.uint8) 
b = np.array([(a[2*i]<<8)+a[2*i+1] for i in range(0, len(a) // 2)]).astype(np.uint16) 
 
print("a: {}".format(a)) # a: [0x31 0x41 0x59 0x26 0x53 0x58 0x97 0x93] 
print("b: {}".format(b)) # b: [0x3141 0x5926 0x5358 0x9793] 

我需要这个用于非常大的数组(或多或少),所以我想知道这是否可以在 Python 中更有效地完成。

请您参考如下方法:

b = a.view(np.uint16) 

这是一个危险且容易出错的操作。请记住您在 C++ 中应该牢记的所有相同注意事项,例如字节顺序。您还需要担心其他注意事项,例如不连续的数组内存布局。至少严格的别名是别人的问题;该实现可能违反了 C 严格的别名规则,但希望他们正在设置编译器标志或其他东西以获得定义的行为。 (uint8 是 unsigned char,因此不适用严格的别名,但 ndarray.view 也允许 uint64->float64 重新解释。)