Hacker News new | past | comments | ask | show | jobs | submit login

Or, if you need a "static" variable for other purposes, the usual alternative is to just use a global variable, but if for some reason you can't (or you don't want to) you can use the function itself!

    def f():
        if not hasattr(f, "counter"): 
            f.counter = 0
    
        f.counter += 1
        return f.counter

    print(f(),f(),f())

    > 1 2 3



I didn’t realize that the function was available in its own scope. This information is going to help me do horrible things with pandas.


This is very important for self-recursion.


Is there something that isn't "self-recursion"?


Mutual recursion. Horrible example, don’t use this:

  even 0 = true
  even n = not (odd n-1)
  odd 0 = false
  odd n = not (even n-1)


That should be

  even 0 = true
  even n = odd n-1

  odd 0 = false
  odd n = even n-1
I fed a C version of this (with unsigned n to keep the nasal daemons at bay) to clang and observed that it somehow manages to see through the mutual recursion, generating code that doesn't recurse or loop.


You are correct, I don't know why I put the nots in there. Either way, demonstrates mutual recursion.


This is very important for self-recursion.


This is very important for self-recursion.


RecursionError: maximum recursion depth exceeded



This is very important for self-recursion.


In Python you'd maybe think, smart, then my counter is a fast local variable. But you look up (slow) the builtin hasattr and the module global f anyway to get at it. :)

I looked at python dis output before writing this, you can look at how it specializes in 3.11. But there's also 4 occurences of LOAD_GLOBAL f in the disassembly of this function, all four self-references to f go through module globals, which shows the kind of "slow" indirections Python code struggles with (and can still be optimized, maybe?)

You could scratch your head and wonder why even inside itself, why is the reference to the function itself going through globals? In the case of a decorated or otherwise monkeypatched function, it has to still refer to the same name.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: