On Fri, May 28, 2021 at 12:25 AM Paul Moore email@example.com wrote:
On Thu, 27 May 2021 at 15:04, Chris Angelico firstname.lastname@example.org wrote:
def static(**kw): def deco(func): statics = types.SimpleNamespace(**kw) @functools.wraps(func) def f(*a, **kw): func(*a, **kw, _statics=statics) return f return deco
@statics(n=0) def count(*, _statics): _statics.n += 1 return _statics.n
Add it to the pile of clunky options, but it's semantically viable. Unfortunately, it's as introspectable as a closure (that is: not at all).
Still arguably clunky, still doesn't have any performance benefits, but possibly a better interface to function attributes than just using them in their raw form.
def static(**statics): def deco(func): for name, value in statics.items(): setattr(func, name, value) func.__globals__["__me__"] = func return func return deco
@static(a=1) def f(): print(__me__.a)
Can't use globals like that, since there's only one globals() dict per module. It'd require some compiler magic to make __me__ work the way you want. But on the plus side, this doesn't require a run-time trampoline - all the work is done on the original function object.
So, yeah, add it to the pile.