What is the Python equivalent of static variables inside a function?

前端 未结 26 2740
天命终不由人
天命终不由人 2020-11-22 00:45

What is the idiomatic Python equivalent of this C/C++ code?

void foo()
{
    static int counter = 0;
    counter++;
          


        
相关标签:
26条回答
  • 2020-11-22 01:46

    Here is a fully encapsulated version that doesn't require an external initialization call:

    def fn():
        fn.counter=vars(fn).setdefault('counter',-1)
        fn.counter+=1
        print (fn.counter)
    

    In Python, functions are objects and we can simply add, or monkey patch, member variables to them via the special attribute __dict__. The built-in vars() returns the special attribute __dict__.

    EDIT: Note, unlike the alternative try:except AttributeError answer, with this approach the variable will always be ready for the code logic following initialization. I think the try:except AttributeError alternative to the following will be less DRY and/or have awkward flow:

    def Fibonacci(n):
       if n<2: return n
       Fibonacci.memo=vars(Fibonacci).setdefault('memo',{}) # use static variable to hold a results cache
       return Fibonacci.memo.setdefault(n,Fibonacci(n-1)+Fibonacci(n-2)) # lookup result in cache, if not available then calculate and store it
    

    EDIT2: I only recommend the above approach when the function will be called from multiple locations. If instead the function is only called in one place, it's better to use nonlocal:

    def TheOnlyPlaceStaticFunctionIsCalled():
        memo={}
        def Fibonacci(n):
           nonlocal memo  # required in Python3. Python2 can see memo
           if n<2: return n
           return memo.setdefault(n,Fibonacci(n-1)+Fibonacci(n-2))
        ...
        print (Fibonacci(200))
        ...
    
    0 讨论(0)
  • 2020-11-22 01:48

    A global declaration provides this functionality. In the example below (python 3.5 or greater to use the "f"), the counter variable is defined outside of the function. Defining it as global in the function signifies that the "global" version outside of the function should be made available to the function. So each time the function runs, it modifies the value outside the function, preserving it beyond the function.

    counter = 0
    
    def foo():
        global counter
        counter += 1
        print("counter is {}".format(counter))
    
    foo() #output: "counter is 1"
    foo() #output: "counter is 2"
    foo() #output: "counter is 3"
    
    0 讨论(0)
提交回复
热议问题