On Thu, 27 May 2021 at 14:22, Chris Angelico rosuav@gmail.com wrote:
Note that the statics *must* be defined on the function, NOT on the code object. Just like function defaults, they need to be associated with individual instances of a function.
f = [] for n in range(10):
... def spam(n=n): ... # static n=n # Same semantics ... print(n) ... f.append(spam) ...
Each spam() should print out its particular number, even though they all share the same code object.
This reminds me, if we ignore the performance aspect, function attributes provide this functionality, but there's a significant problem with using them because you can't access them other than by referencing the *name* of the function being defined.
def f():
... print(f.i) ...
f.i = 1 g = f del f g()
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 1, in f NameError: name 'f' is not defined
OK, you can, if you're willing to mess around with sys._getframe and make some dodgy assumptions:
def me():
... parent = sys._getframe(1) ... for obj in parent.f_globals.values(): ... if getattr(obj, "__code__", None) == parent.f_code: ... return obj ...
def f():
... print(me().i) ...
f.i = 1 g = f del f g()
1
It would be nice to have a better way to reference function attributes from within a function. (This would also help write recursive functions that could be safely renamed, but I'm not sure many people would necessarily think that's a good thing ;-))
Paul