Python 为什么我们可以使用变量名来获取存储在其中的数据?

Python 为什么我们可以使用变量名来获取存储在其中的数据?,python,arrays,numpy,Python,Arrays,Numpy,在使用Python时,我遇到了一个长期困扰我的问题。比如说,我使用numpy定义一个数组x=np.array([1,2]) 我认为,这意味着x是classarray的一个实例。此外,本教程还指出,[1,2]实际上存储在x.data中。但是,我通过实例名称x而不是Python中的x.data获得数据 这是怎么发生的?实例名称x和x.data之间存在链接 x和x.data是不同的类型,尽管它们在解释内存中相同位置的数据 In [1]: import numpy as np In [2]: x =

在使用Python时,我遇到了一个长期困扰我的问题。比如说,我使用numpy定义一个数组
x=np.array([1,2])

我认为,这意味着
x
是class
array
的一个实例。此外,本教程还指出,
[1,2]
实际上存储在
x.data
中。但是,我通过实例名称
x
而不是Python中的
x.data
获得数据


这是怎么发生的?实例名称
x
x.data
之间存在链接

x
x.data
是不同的类型,尽管它们在解释内存中相同位置的数据

In [1]: import numpy as np

In [2]: x = np.array([1,2])

In [3]: type(x)
Out[3]: numpy.ndarray

In [4]: type(x.data)
Out[4]: buffer
x.data
是指向组成内存中数组对象的底层字节缓冲区的指针,在中引用

当我们检查底层数据类型(
dtype
)时,数组正在存储数据,如下所示:

In [5]: x.dtype
Out[5]: dtype('int64')
int64
由64位或8个字节(一个字节中有8位)组成。这意味着
x
的底层缓冲区,
x.data
应该是长度为16的
缓冲区。我们在此确认:

In [6]: len(x.data)
Out[6]: 16
最后,我们可以查看缓冲区的实际值,以了解Python如何将值存储在内存中:

In [7]: for i in range(len(x.data)): print ord(x.data[i])
1
0
0
0
0
0
0
0
# first 8 bytes above, second 8 below
2
0
0
0
0
0
0
0
我们使用返回字节的值,因为
numpy
将值存储为8位(1字节)字符串

由于每个字节仅存储8位信息,因此循环打印的上述值都不会超过255

x
x.data
之间的链接是
x.data
指向您在检查
x
时看到的值在内存中的位置
numpy
使用
ndarray
类型作为内存中较低级别存储之上的抽象,以便于在较高级别处理数组,例如在索引1处获取
x
的值:

In [8]: x[1]
Out[8]: 2

不需要自己实现正确的偏移和二进制到整数的转换。

x
x.data
是不同的类型,尽管它们在解释内存中相同位置的数据

In [1]: import numpy as np

In [2]: x = np.array([1,2])

In [3]: type(x)
Out[3]: numpy.ndarray

In [4]: type(x.data)
Out[4]: buffer
x.data
是指向组成内存中数组对象的底层字节缓冲区的指针,在中引用

当我们检查底层数据类型(
dtype
)时,数组正在存储数据,如下所示:

In [5]: x.dtype
Out[5]: dtype('int64')
int64
由64位或8个字节(一个字节中有8位)组成。这意味着
x
的底层缓冲区,
x.data
应该是长度为16的
缓冲区。我们在此确认:

In [6]: len(x.data)
Out[6]: 16
最后,我们可以查看缓冲区的实际值,以了解Python如何将值存储在内存中:

In [7]: for i in range(len(x.data)): print ord(x.data[i])
1
0
0
0
0
0
0
0
# first 8 bytes above, second 8 below
2
0
0
0
0
0
0
0
我们使用返回字节的值,因为
numpy
将值存储为8位(1字节)字符串

由于每个字节仅存储8位信息,因此循环打印的上述值都不会超过255

x
x.data
之间的链接是
x.data
指向您在检查
x
时看到的值在内存中的位置
numpy
使用
ndarray
类型作为内存中较低级别存储之上的抽象,以便于在较高级别处理数组,例如在索引1处获取
x
的值:

In [8]: x[1]
Out[8]: 2

而不需要自己实现正确的偏移和二进制到整数的转换。

非常好的答案。我很感激他们。但是关于实例名“x”和x的属性x.data之间的联系的解释仍然让我感到困惑。也许,我应该再举一个让我困惑的例子,如下所示。我使用pytorch定义一个变量x,计算并得到它的梯度x.grad,意思是grad是实例x的一个属性。但是,我们可以使用x.grad.data.zero_u2;()将x.grad设置为零,这意味着data.zero_2;()是x.grad的方法。为什么属性有一个方法?非常感谢。
x
只是一个python
,因此它可以在其上定义任意属性,可以包括其他类、函数和值,包括变异并使用存储在类本身中的值的函数。如果您想知道
data
属性实际上是如何在
ndarray
type对象上定义的,那么在Python中的OOP上可能会有所帮助,这是非常有用的答案。我很感激他们。但是关于实例名“x”和x的属性x.data之间的联系的解释仍然让我感到困惑。也许,我应该再举一个让我困惑的例子,如下所示。我使用pytorch定义一个变量x,计算并得到它的梯度x.grad,意思是grad是实例x的一个属性。但是,我们可以使用x.grad.data.zero_u2;()将x.grad设置为零,这意味着data.zero_2;()是x.grad的方法。为什么属性有一个方法?非常感谢。
x
只是一个python
,因此它可以在其上定义任意属性,可以包括其他类、函数和值,包括变异并使用存储在类本身中的值的函数。如果您想知道
data
属性实际上是如何在
ndarray
type对象上定义的,那么在Python中的OOP上可能会有所帮助,这真的很有帮助