简体   繁体   English

我怎样才能在 lambda ZC1C425268E68385D1AB5074F14C1

[英]How can I get the function object inside a lambda function

Sorry if this is very lame, but I'm pretty new to Python.抱歉,如果这很蹩脚,但我对 Python 还是很陌生。

As in Python everything is an object, I assume in every object the object itself can be get somehow.就像在 Python 中一样,一切都是 object,我假设在每个 object 中,ZA8CFDE6331BD59EB2AC96F89111C4 本身都可以得到。 In object methods the self variable contains it.在 object 方法中, self变量包含它。 From the object reference the class object can be get (like type(self) ).从 object 参考 class object 可以得到(如type(self) )。 But how this could be got inside a lambda?但这怎么能在 lambda 中得到呢?

I could figure out for a normal function:我可以找出一个正常的 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: output 看起来像这样:

named_func <function named_func at 0x7f56e368c2f0> 15

Unfortunately in a lambda the inspect.stack()[0].function gives <lambda> inside the lambda.不幸的是,在 lambda 中, inspect.stack()[0].function在 lambda 中给出了<lambda>

Is there a way to get the function object inside a lambda?有没有办法在 lambda 中获取 function object ? Is there a way to get function object directly (not using the name of the function)?有没有办法直接获取function object(不使用函数名)? I imagined __self__ , but it does not work.我想象__self__ ,但它不起作用。

UPDATE更新

I tried something like this in lambda:我在 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?但例如,在这种情况下,有没有办法获得 lambda object 字段xxx For this the lambda object should be got somehow.为此,应该以某种方式获得 lambda object。

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.基本上,给定stack ,您可以找到code object,然后使用gc模块您可以找到对 lambda 的引用。

Example with @Tomalak 's factorial lambda! @Tomalak的阶乘 lambda 示例!

import gc
import inspect


def current_lambda():
    lambda_code = inspect.stack()[1].frame.f_code
    lambda_obj = gc.get_referrers(lambda_code)[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

We can now use a new python syntax to make it shorter and easier to read, without the need to define a new function for this purpose.我们现在可以使用新的 python 语法使其更短且更易于阅读,而无需为此目的定义新的 function。

You can find two examples below:您可以在下面找到两个示例:

Fibonacci:斐波那契:

(f:=lambda x: 1 if x <= 1 else f(x - 1) + f(x - 2))(5)

Factorial:阶乘:

(f:=lambda x: 1 if x == 0 else x*f(x - 1))(5)

We use := to name the lambda: use the name directly in the lambda itself and call it right away as an anonymous function.我们使用:=来命名 lambda:直接在 lambda 本身中使用该名称,并立即将其称为匿名 function。

So in your particular use-case it would give something like that:因此,在您的特定用例中,它会给出类似的结果:

print((f:=lambda: f.__hash__())())  # prints the hash for example

You can do whatever you want with that f variable now (inside the lambda).你现在可以用那个f变量做任何你想做的事情(在 lambda 内)。

But in fact, if you don't mind multi-lines for your code, you could also just use the name directly and do something like that:但事实上,如果您不介意代码多行,您也可以直接使用名称并执行以下操作:

f = lambda : f.xxx
f.xxx = 2
print(f())

(see https://www.python.org/dev/peps/pep-0572 for more information about this := operator) (有关此操作的更多信息,请参见https://www.python.org/dev/peps/pep-0572 :=

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM