2017-08-26 89 views
-1
>>> a=5 
>>> b=6 
>>> id(a) 
10914496 
>>> id(b) 
10914528 
>>> c='Hello' 
>>> d='World' 
>>> id(c) 
139973573252184 
>>> id(d) 
139973616356744 
>>> e=(4>5) 
>>> f=(4<5) 
>>> id(e) 
10739968 
>>> id(f) 
10740000 
  1. 为什么string和boolean/int数据类型的地址长度如此不同?
  2. 为什么随后的声明在地址上有相当大的不同,与数据类型的大小相比?

更新#1为什么不同数据类型的地址不同[Python]?

>>> id(c) 
139973616356856 
>>> id(c[0]) 
139973652926112 
>>> id(c[1]) 
139973653190728 
>>> id(c[2]) 
139973653634272 
>>> id(c[3]) 
139973653302104 

我有这个疑问,因为我学过C++第一(说实话,用Turbo C++)和字符串的地址都是用Python定义方式是什么很大的不同发生在C++中。我想这在Python中是好的,因为我们不能通过它在Python中的地址来访问对象,对吗?

此外,c和c [0]具有不同的地址有什么意义?对于某些人来说,这些问题可能是不必要的,但我很好奇,不知道Python如何为各种数据类型(特别是字符串)分配地址。

+0

另外解释downvote,因为这是我在这个网站上的第一个问题。 –

回答

1

首先,我们应该从Python开始,它的工作方式与C不同。在C中,数组只是一块内存。在Python中,它是一个对象。 cc[0]id()与结果不一样。

其次,你应该认识到Python中的每一件事都是一个对象。在C中,当你想做类似c[0]的事情时,你正在请求一系列内存位置的第一个值。在Python中,情况并非一定如此。对于一个标准列表,它由一个数组支持,但是它的地址对你来说是隐藏的。你看到的是通过id()对象的地址。在这种情况下,c是一个字符串,但这样是c[0](没有字符类型在Python)。这意味着当您要求c[0]时,Python正在创建一个新字符串来表示您请求的字符(或者说,子字符串)。幸运的是,Python实际上并没有每次创建一个新的字符串,因为Python会自动实现一个字符的字符串。

另外,记住,Python对象有一个结构和太消耗内存。关于C的最好的事情之一是能够非常控制内存布局,但是你在Python中失去了这方面的能力。翻盖面是,你不必做手工分配和内存,这是一种解脱(我做了很多C和Python编程,让我看到了好处)释放。

三,很多更多的内存分配和释放在Python中发生。根据构建Python的方式以及分配内存的底层操作系统策略,可能会发生任何数量的事情,导致地址不会按顺序增加。但由于一切是一个对象,有一个潜在的分配正在发生的一切。

我有这个疑问,因为我学过C++第一(说实话,用Turbo C++)和字符串的地址都是用Python定义方式是用C会发生什么++非常不同。我想这在Python中是好的,因为我们不能通过它在Python中的地址来访问对象,对吗?

yes和no。当你说c[0]时,在引擎盖下面正在运行一个特殊的方法来从字符串中检索子字符串。这与你在C++中获得的不同。但是,Python确实将字符串作为字节序列进行有效存储。所以只是因为你看不到效率检查地址,并不意味着它不在那里。另外,正如我上面提到的,c[0]返回一个新的字符串,表示您想要的子字符串。 Python在这里很聪明,会返回一个1个字符的字符串,但它将是一个内部字符串。你可以看到一些字母具有相同的地址:

>>> for c in "hobo": 
...  print c, id(c) 
... 
h 4434994600 
o 4434861432 
b 4434859712 
o 4434861432 

你可以看到,"o"共享相同的地址字符串 - 顺便说一句,这个例子的Python 2,但在Python 3

存在同样的质量

而且你是正确的,你不能访问由它的地址对象 - 至少这是不是语言的一个特征。如何生成ids是一个实现细节,但是你应该指望每个Python解释器都这样做。

另外,为c和c [0]设置不同的地址有什么意义?对于某些人来说,这些问题可能是不必要的,但我很好奇,不知道Python如何为各种数据类型(特别是字符串)分配地址。

我解释这上面,而是概括:cc[0]比在C.在Python不同,首先是字符串和第二请求包含字符串的第一个字符的子字符串。

Python做在许多领域使用的舞台风格的内存管理方案,但在大多数情况下,你不需要关心这个。如果你好奇,我建议你看看Python source codePython子目录具有许多语言和低级运行时支持位。同时也意识到,Python也预先缓存了一些内容,这也可以解释上述地址中的差异。

2

根据您的计算机架构,数据类型将以不同的字节长度存储在内存中。例如,一个字符串中的每个ASCII字符需要一个字节来存储它,而整数可以以任何位长度存储,直至达到极限,这取决于所存储数字的大小。我不完全确定,但python可能会在分配的内存的不同区域中存储不同的数据类型。

Python在分配的内存中存储的内容不仅仅是你给它的变量。 IDE也在该领域运行。因此,在两个分配之间可能存储了其他一些变量。

对于更新#1,看看this

+0

我明白你的观点。谢谢。也请看看我的更新#1。 –

1

id恰好是在地址CPython的是一个实现细节;它们只能保证与同时存在的对象不同。

您观察到的分组是因为CPython预先创建了一些对象,包括-5256以及TrueFalse。在一般情况下,这些值不会出现在任何其他地址上,因为它们是不可变的类型,所以可以做到这一点。

第二个问题,关于字符串中的切片,是因为Python的字符串对象不相互引用。没有字符类型,因此从字符串中提取字符会生成新的字符串。同样,其中一些可能被缓存(实际字符串)。字符串对象的地址不一定是其内容的地址。

您可以使用​​来访问您熟悉的C类型,但这样做通常很尴尬且有风险。例如,如果你将一个Python字符串传递给一个改变一个C字符串的函数,那么你会破坏字符串本身; Python期望字符串是不可变的,并且可以共享它们并缓存它们的哈希值。

相关问题