Python itertools计数器的当前值是多少
Python(2.7.9)中的Python itertools计数器的当前值是多少,python,itertools,Python,Itertools,Python(2.7.9)中的itertools.count计数器对于线程安全计数非常方便。但是,如何获取计数器的当前值 每次调用next(),计数器都会递增并返回最后一个值: 到目前为止,一切顺利 如果不调用next(),我无法找到获取计数器当前值的方法,这会产生增加计数器或使用repr()函数的不良副作用 以下是上文的内容: print repr(x) # "count(3)" 因此,您可以解析repr()的输出。差不多 current_value = int(repr(x)[6:-1]
itertools.count
计数器对于线程安全计数非常方便。但是,如何获取计数器的当前值
每次调用next()
,计数器都会递增并返回最后一个值:
到目前为止,一切顺利
如果不调用next()
,我无法找到获取计数器当前值的方法,这会产生增加计数器或使用repr()
函数的不良副作用
以下是上文的内容:
print repr(x) # "count(3)"
因此,您可以解析repr()
的输出。差不多
current_value = int(repr(x)[6:-1])
他会耍花招,但真的很难看
有没有办法更直接地获取计数器的当前值?根据,无法访问函数的当前值itertools.count()
是来自itertools
模块的生成器方法。因此,通常只需将生成器当前值的值分配给变量即可
只需存储下一次调用的结果:
current_value = x.next()
或(用于python版本的内置python方法)≥ (2.6)
如果您想增加一些语法方面的支持,您可以创建一个包装器函数或实用程序装饰器类,但赋值是标准的。是一个生成器,要做您想做的事情并不容易
如果您想在多个位置使用它的值,我建议您通过.next()
获取一个值并将其存储在变量中。若您担心计数器在这两次使用之间可能会递增,那个么无论如何您都需要将它们都放在一个表中
如果您不想用这些检查生成的额外“+1”污染该计数器,您可以再使用一个计数器来计数检查(也将其放在临界部分)。从前者中减去后者会得到你所需要的
另外,你真的确定线程安全吗?文档页面没有关于线程的内容。使用源代码,Luke
据报道,这是不可能的
typedef struct {
PyObject_HEAD
Py_ssize_t cnt;
PyObject *long_cnt;
PyObject *long_step;
} countobject;
当前状态存储在cnt
和long\u cnt
成员中,它们都不在对象API中公开。正如您所建议的,可以检索它的唯一位置是object\uuuu repr\uuuu
注意,解析字符串时,必须考虑非奇异增量情况。code>repr(itertools.count(123,4))等于
'count(123,4)
-在这种情况下,您提出的逻辑将失败。今天遇到了同样的问题。以下是我最终得到的结果:
class alt_count:
def __init__(self, start=0, step=1):
self.current = start - step
self.step = step
def __next__(self):
self.current = self.current + self.step
return self.current
应该为您提供几乎所有的功能以及current
属性
i = alt_count()
print(next(i)) # 0
print(next(i)) # 1
print(i.current) # 1
如果不需要当前值,我发现使用这个简单的方法也可以。请注意,这仅适用于Python版本>3
def alt_next_maker(start=0, step=1):
res = start - step
def alt_next():
nonlocal res, step
res = res + step
return res
return alt_next
如果您不想使用该模块,可以将其用作简单的替代方案
文件中还提到了以下内容:
def count(start=0, step=1):
# count(10) --> 10 11 12 13 14 ...
# count(2.5, 0.5) -> 2.5 3.0 3.5 ...
n = start
while True:
yield n
n += step
另一种在不推进迭代器的情况下获取下一个值的方法是滥用复制协议:
>>> c = itertools.count()
>>> c.__reduce__()[1][0]
0
>>> next(c)
0
>>> c.__reduce__()[1][0]
1
或者直接从对象副本中获取:
>>> from copy import copy
>>> next(copy(c))
1
它在哪里说它是线程安全的?@MattiVirkkunen我读过,并且在自己测试之后,似乎
next(count())
确实是线程安全的。测试线程安全并不容易。此外,如果您依靠GIL来保持线程安全,那么仅仅使用一个普通变量和+=
,真的有什么区别吗?@Carl它是在一个名为count\u repr()的C函数中实现的。
@MattiVirkkunen+=
肯定不是线程安全的。太好了,谢谢你很好地解决了这个问题。现在我明白了为什么这是不可能的,至少:-)
def count(start=0, step=1):
# count(10) --> 10 11 12 13 14 ...
# count(2.5, 0.5) -> 2.5 3.0 3.5 ...
n = start
while True:
yield n
n += step
>>> c = itertools.count()
>>> c.__reduce__()[1][0]
0
>>> next(c)
0
>>> c.__reduce__()[1][0]
1
>>> from copy import copy
>>> next(copy(c))
1