Why doesn't Python have static variables?

后端 未结 9 2435
暗喜
暗喜 2020-11-27 14:48

There is a questions asking how to simulate static variables in python.

Also, on the web one can find many different solutions to create static variables. (Though I

相关标签:
9条回答
  • 2020-11-27 15:19

    In Python 3, I would use a closure:

    def makefoo():
        x = 0
        def foo():
            nonlocal x
            x += 1
            return x
        return foo
    
    foo = makefoo()
    
    print(foo())
    print(foo())
    
    0 讨论(0)
  • 2020-11-27 15:19

    It's a design choice.

    I'm assuming Guido thinks you don't need them very often, and you never really need them: you can always just use a global variable and tell everyone to keep their greasy paws offa' your variable ;-)

    0 讨论(0)
  • 2020-11-27 15:25

    I think most uses of local static variables is to simulate generators, that is, having some function which performs some iteration of a process, returns the result, but mantains the state for the subsequent invocation. Python handles this very elegantly using the yield command, so it seems there is not so much need for static variables.

    0 讨论(0)
  • 2020-11-27 15:36

    The idea behind this omission is that static variables are only useful in two situations: when you really should be using a class and when you really should be using a generator.

    If you want to attach stateful information to a function, what you need is a class. A trivially simple class, perhaps, but a class nonetheless:

    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()
    

    If you want your function's behavior to change each time it's called, what you need is a generator:

    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()
    

    Of course, static variables are useful for quick-and-dirty scripts where you don't want to deal with the hassle of big structures for little tasks. But there, you don't really need anything more than global — it may seem a but kludgy, but that's okay for small, one-off scripts:

    def foo():
        global bar
        do_stuff(bar)
    
    foo()
    foo()
    
    0 讨论(0)
  • 2020-11-27 15:36

    From one of your comments: "I'd like to use them to cache things loaded from disk. I think it clutters the instance less, if I could assign them to the function"

    Use a caching class then, as a class or instance attribute to your other class. That way, you can use the full feature set of classes without cluttering other things. Also, you get a reusable tool.

    This shows that on SO it always pays off to state one's problem instead of asking for a specific, low level solution (e.g. for a missing language feature). That way, instead of endless debates about simulating "static" (a deprecated feature from an ancient language, in my view) someone could have given a good answer to you problem sooner.

    0 讨论(0)
  • 2020-11-27 15:38

    The answer's pretty much the same as why nobody uses static methods (even though they exist). You have a module-level namespace that serves about the same purpose as a class would anyway.

    0 讨论(0)
提交回复
热议问题