Python:优雅地增加全局变量的方法

5

在Python中优雅地增加全局变量的方法:

这是我目前的代码:

my_i = -1
def get_next_i():
    global my_i
    my_i += 1
    return my_i

使用生成器:

my_iter = iter(range(100000000)) 
def get_next_i():
    return next(my_iter)

具有类:

class MyI:
    MyI.my_i = -1
    @staticmethod
    def next():
        MyI.my_i += 1
        return MyI.my_i
  • 第一个方法比较冗长,我不认为它是一种更好的编码方式。
  • 第二个方法更加优雅,但有一个上限。
  • 第三个方法虽然很长,但至少没有全局变量需要处理。

那么,这些方法的最佳替代方案是什么?

这些函数的目的是为了给我的代码中的特定事件分配唯一的编号。代码不仅仅是单个循环,因此在这里使用 for i in range(...): 不合适。后续版本可能会使用多个索引分配给不同的事件。第一个代码需要重复来解决这样的问题。(get_next_i(), get_next_j(), ...)

谢谢。


4
只需使用 itertools.count 吗? - jonrsharpe
第三个虽然很长,但至少没有全局变量可供使用——它仍然有一个全局变量,只是拼写为my_module.MyI.my_i而不是my_module.my_i。就担心全局变量危险的目的而言,全局变量是任何人都可以随意访问的东西。将其从模块命名空间移动到类命名空间中并不能消除全局变量的潜在问题。您需要解决潜在的问题(或同时解决)。 - Steve Jessop
是的,但你不会将变量命名为MyI.my_i并破坏next()方法的功能。第一个例子很差,因为编写for my_i in range(123):将破坏get_next_i()函数。 - Szabolcs Dombi
@Dombi:是的,“显然”在模块级别上使用for my_i in range(123:)会重新分配全局变量。但是我明白了:我不会在模块级别编写这样的代码,但那些这样做的人将遇到此问题。那些在类级别编写for my_i in xrange(123):的人将遇到相同的问题,但我承认这更加罕见。 - Steve Jessop
2个回答

6

正如其他人所建议的,itertools.count() 是最好的选择,例如:

import itertools

global_counter1 = itertools.count()
global_counter2 = itertools.count()
# etc.

然后,当你需要时,只需调用next

def some_func():
    next_id = next(global_counter1)

编辑:将只在Python 2中有效的global_counter1.next()更改为next(global_counter1),这也适用于Python 3。


4

您可以创建一个具有无限循环的生成器。每次调用 next(generator) 将返回下一个值,没有限制。参见Python中的“yield”关键字是什么?

def create_generator()
    i=0
    while True:
        i+=1
        yield i

generator = create_generator()
print(next(generator))
print(next(generator))

2
或者,只需使用itertools.count即可完全实现此功能?(除了可选的起始和步长参数...) - Jon Clements
counts = {'i': count(), 'j': count(), 'k': count()} - 然后访问 next(counts['j'])next(counts['k']) 并保持 counts 可访问... - Jon Clements
submit as an answer - Szabolcs Dombi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接