生成器没有存储在内存中,那么我怎么会在循环结束后得到这些值呢



创建一个循环用于生成一系列数字

import ctypes
g = [ ]
for item1 in range(10):
print(f'memory address of {item1} = {id(item1)}')
g.append(id(item1))

这里我的循环结束了,但唯一存储的是位置或内存地址,而不是数字

检查该内存地址的值

for item in g:
a = ctypes.cast(item, ctypes.py_object).value
print(f'values at that memory address = {a}')

此处
a=ctypes.cast(项,ctypes.py_object(.value
给出存储在该内存地址的值

输出

C:UsersAdminDesktoppythonProjectvenvScriptspython.exe C:/Users/Admin/Desktop/pythonProject/main.py 
memory address of 0 = 140709883771936
memory address of 1 = 140709883771968
memory address of 2 = 140709883772000
memory address of 3 = 140709883772032
memory address of 4 = 140709883772064
memory address of 5 = 140709883772096
memory address of 6 = 140709883772128
memory address of 7 = 140709883772160
memory address of 8 = 140709883772192
memory address of 9 = 140709883772224

我的循环在soo之前已经结束,根据生成器,它们不再在内存中,但这些内存地址仍然显示前一个循环的那些元素的值

values at that memory address = 0
values at that memory address = 1
values at that memory address = 2
values at that memory address = 3
values at that memory address = 4
values at that memory address = 5
values at that memory address = 6
values at that memory address = 7
values at that memory address = 8
values at that memory address = 9
Process finished with exit code 0

这只是cpython的一个实现细节,它为数字-4到256预构建了singleton。Python对这些数字有自己的引用。循环添加和删除引用,但原始引用仍然存在,从而使值保持在内存中的同一位置。

如果选择此序列之外的范围,则会得到不同的结果。

import ctypes
g = [ ]
for item1 in range(257, 267):
print(f'memory address of {item1} = {id(item1)}')
g.append(id(item1))
for item in g:
a = ctypes.cast(item, ctypes.py_object).value
print(f'values at that memory address = {a}')

输出

memory address of 257 = 139740170741360
memory address of 258 = 139740170743920
memory address of 259 = 139740170743952
memory address of 260 = 139740170743856
memory address of 261 = 139740170743824
memory address of 262 = 139740170741744
memory address of 263 = 139740170743792
memory address of 264 = 139740170744048
memory address of 265 = 139740170744080
memory address of 266 = 139740170744112
values at that memory address = 139740170743920
values at that memory address = 139740170743952
values at that memory address = 139740170743856
values at that memory address = 139740170743824
values at that memory address = 139740170741744
values at that memory address = 139740170743792
values at that memory address = 139740170744048
values at that memory address = 139740170744080
values at that memory address = 139740170744112
values at that memory address = 266

range不是生成器。它是从Python中的基类object继承的一系列正整数intclass,因此它不是函数或生成器。但如果你浏览它的类代码,你可以看到__iter__方法,从中你可以说,它具有迭代的功能,而在hud下面的for循环使用iter(),这是迭代。因此,它应该能够迭代范围

代码

help(range)

输出


C:UsersAdminPycharmProjectspythonProject1venvScriptspython.exe C:/Users/Admin/PycharmProjects/pythonProject1/main.py 
Help on class range in module builtins:
class range(object)
|  range(stop) -> range object
|  range(start, stop[, step]) -> range object
|  
|  Return an object that produces a sequence of integers from start (inclusive)
|  to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
|  start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
|  These are exactly the valid indices for a list of 4 elements.
|  When step is given, it specifies the increment (or decrement).
|  
|  Methods defined here:
|  
|  __bool__(self, /)
|      self != 0
|  
|  __contains__(self, key, /)
|      Return key in self.
|  
|  __eq__(self, value, /)
|      Return self==value.
|  
|  __ge__(self, value, /)
|      Return self>=value.
|  
|  __getattribute__(self, name, /)
|      Return getattr(self, name).
|  
|  __getitem__(self, key, /)
|      Return self[key].
|  
|  __gt__(self, value, /)
|      Return self>value.
|  
|  __hash__(self, /)
|      Return hash(self).
|  
|  __iter__(self, /)
|      Implement iter(self).
|  
|  __le__(self, value, /)
|      Return self<=value.
|  
|  __len__(self, /)
|      Return len(self).
|  
|  __lt__(self, value, /)
|      Return self<value.
|  
|  __ne__(self, value, /)
|      Return self!=value.
|  
|  __reduce__(...)
|      Helper for pickle.
|  
|  __repr__(self, /)
|      Return repr(self).
|  
|  __reversed__(...)
|      Return a reverse iterator.
|  
|  count(...)
|      rangeobject.count(value) -> integer -- return number of occurrences of value
|  
|  index(...)
|      rangeobject.index(value) -> integer -- return index of value.
|      Raise ValueError if the value is not present.
|  
|  ----------------------------------------------------------------------
|  Static methods defined here:
|  
|  __new__(*args, **kwargs) from builtins.type
|      Create and return a new object.  See help(type) for accurate signature.
|  
|  ----------------------------------------------------------------------
|  Data descriptors defined here:
|  
|  start
|  
|  step
|  
|  stop

Process finished with exit code 0

最新更新