为什么Python没有静态变量?

Geo*_*lly 47 python

有一个问题询问如何在python中模拟静态变量.

此外,在Web上可以找到许多不同的解决方案来创建静态变量.(虽然我还没有看到我喜欢的那个.)

为什么Python不支持方法中的静态变量?这被认为是unpythonic还是与Python的语法有关?

编辑:

我特意询问了设计决策的原因,但我没有提供任何代码示例,因为我想避免解释来模拟静态变量.

Ben*_*ank 77

这个遗漏背后的想法是静态变量只在两种情况下有用:当你真的应该使用一个类时,你何时应该使用一个生成器.

如果要将有状态信息附加到函数,则需要的是类.也许是一个简单的类,但是仍然是一个类:

def foo(bar):
    static my_bar # doesn't work

    if not my_bar:
        my_bar = bar

    do_stuff(my_bar)

foo(bar)
foo()

# -- becomes ->

class Foo(object):
    def __init__(self, bar):
        self.bar = bar

    def __call__(self):
        do_stuff(self.bar)

foo = Foo(bar)
foo()
foo()
Run Code Online (Sandbox Code Playgroud)

如果您希望每次调用函数的行为都会改变,那么您需要的是生成器:

def foo(bar):
    static my_bar # doesn't work

    if not my_bar:
        my_bar = bar

    my_bar = my_bar * 3 % 5

    return my_bar

foo(bar)
foo()

# -- becomes ->

def foogen(bar):
    my_bar = bar

    while True:
        my_bar = my_bar * 3 % 5
        yield my_bar

foo = foogen(bar)
foo.next()
foo.next()
Run Code Online (Sandbox Code Playgroud)

当然,静态变量快速和肮脏的脚本,让你不想处理大结构的小任务的麻烦有用.但在那里,你真的不需要任何东西global- 它可能看起来像一个但很笨拙,但这对于小型的一次性脚本来说是可以的:

def foo():
    global bar
    do_stuff(bar)

foo()
foo()
Run Code Online (Sandbox Code Playgroud)


dav*_*avr 19

类的一个替代方法是函数属性:

def foo(arg):
    if not hasattr(foo, 'cache'):
        foo.cache = get_data_dict()
    return foo.cache[arg]
Run Code Online (Sandbox Code Playgroud)

虽然一个类可能更干净,但这种技术可能很有用,而且在我看来更好,然后是全球性的.

  • @gs:是的,这是一个缺点。我正在寻找某种方法来引用当前函数,而不是使用名称(例如 self ),但我认为没有这样的方法。您可以在最顶部执行“this = foo”,然后在各处引用“this”,这样重命名就很容易维护。 (2认同)

Jos*_*Lee 8

在Python 3中,我会使用一个闭包:

def makefoo():
    x = 0
    def foo():
        nonlocal x
        x += 1
        return x
    return foo

foo = makefoo()

print(foo())
print(foo())
Run Code Online (Sandbox Code Playgroud)


Il-*_*ima 6

我认为局部静态变量的大多数用法是模拟生成器,也就是说,有一些函数可以执行一些进程的迭代,返回结果,但是保留了后续调用的状态.Python使用该yield命令非常优雅地处理它,因此似乎不需要静态变量.


Jon*_*ker 5

这是一个设计选择.

我假设Guido认为你不经常需要它们,你从来没有真正需要它们:你总是可以使用一个全局变量并告诉每个人保持他们的油腻爪子离开你的变量;-)