So just about everything in python is mutable by default, this includes module objects.
For example, you can do this (but you shouldn't)
sys.foo = 'WHY OH WHY DID I DO THIS!?!?'
Now any other module in your program, if they are imported after you set the value.
But really, don't ever do this with the
So this next part involves how names are looked up in python it is a bit more complex, the short simple version though, is that when you are inside a function, first the name is checked in the local function, in this case that would be inside the
lambda, if it can't find it there, it checks the next outer scope, which would be inside
runPreset, it then keeps checking outer scopes, until it hits the module global space. If it can't find it there, a
NameError exception gets raised.
Now if you combine those two facts, the first example is basically inserting the name
smartPreset into the
NKTR_hair_ctrl_helper module's namespace, so that when the drop happens, the lambda will actually find the name when the drop occurs.
This is actually also why the second option works, it just relies on placing everything into a function's scope, which is a bit more portable than relying on module's global space.