Sorry if this is very lame, but I'm pretty new to Python.
As in Python everything is an object, I assume in every object the object itself can be get somehow. In object methods the self variable contains it. From the object reference the class object can be get (like type(self)). But how this could be got inside a lambda?
I could figure out for a normal function:
import inspect
def named_func():
func_name = inspect.stack()[0].function
func_obj = inspect.stack()[1].frame.f_locals[func_name]
print(func_name, func_obj, func_obj.xxx)
named_func.xxx = 15
named_func()
The output looks like this:
named_func <function named_func at 0x7f56e368c2f0> 15
Unfortunately in a lambda the inspect.stack()[0].function gives <lambda> inside the lambda.
Is there a way to get the function object inside a lambda?
Is there a way to get function object directly (not using the name of the function)?
I imagined __self__, but it does not work.
UPDATE
I tried something like this in lambda:
lambda_func = lambda : inspect.stack()[0]
lambda_func.xxx = 2
print(lambda_func())
This prints:
FrameInfo(frame=<frame at 0x7f3eee8a6378, file './test_obj.py', line 74, code <lambda>>, filename='./test_obj.py', lineno=74, function='<lambda>', code_context=['lambda_func = lambda : inspect.stack()[0]\n'], index=0)
But for example is there a way to get the lambda object field xxx in this case? For this the lambda object should be got somehow.
CodePudding user response:
So I think I've figured out how to do this in a very hacky way. I believe this will only work completely correctly if you follow the advice from the answer I found here
Basically, given the stack you can find the code object, and then using the gc module you can find the reference to the lambda.
Example with @Tomalak's factorial lambda!
import gc
import inspect
def current_lambda():
lambda_code = inspect.stack()[1].frame.f_code
candidates = [referrer for referrer in gc.get_referrers(lambda_code)
if inspect.isfunction(referrer) and referrer.__code__ is lambda_code]
if len(candidates) != 1:
raise ValueError("Multiple candidates found! Cannot determine correct function!")
lambda_obj = candidates[0]
return lambda_obj
print((lambda n: 1 if n < 2 else n * current_lambda()(n - 1))(5))
Outputs
120
Revisiting your example:
lambda_func = lambda: current_lambda().xxx
lambda_func.xxx = 10
print(lambda_func())
Outputs:
10
