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

前端 未结 26 3177
天命终不由人
天命终不由人 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))
        ...
    

提交回复
热议问题