Python Lambda表达式的反思
我想“查看”一个lambda表达式,而不计算它。 给出一个像这里这样的表达式Python Lambda表达式的反思,python,python-3.x,lambda,Python,Python 3.x,Lambda,我想“查看”一个lambda表达式,而不计算它。 给出一个像这里这样的表达式 (lambda something: something.x > something.y) 我想访问在lambda之外访问的元素。(即返回一个列表,其中引用了something.x和something.y) 但是,由于我的表达式可能有副作用,(lambda self:self.set_value(15))我希望在不实际调用表达式的情况下执行此操作。此要求使在传递到lambda的对象中重写\uu getattr\
(lambda something: something.x > something.y)
我想访问在lambda
之外访问的元素。(即返回一个列表,其中引用了something.x
和something.y
)
但是,由于我的表达式可能有副作用,(lambda self:self.set_value(15)
)我希望在不实际调用表达式的情况下执行此操作。此要求使在传递到lambda
的对象中重写\uu getattr\uuuu
的可能性无效
简短示例:
l = (lambda something: something.x > something.y)
something = Something()
elements = l.get_accessed_elements(something)
# elements is a list where
# elements[0] points to something.x, and
# elements[1] points to something.y
我自己研究了解析主体,但我必须访问源代码并执行一些字符串魔术来清理源代码行(通过
inspect
收集).这实际上与lambda表达式没有任何关系。但如果您试图查看访问的属性,则始终可以使用打印其参数的\uuuu getattribute\uuuu
方法定义自定义类:
class Something(object):
def __getattribute__(self, name):
print("{} was accessed".format(name))
如果现在将其传递给lambda表达式:
>>> l = lambda something: something.x > something.y
>>> s = Something()
>>> l(s)
x was accessed
y was accessed
注释后编辑它可能不适用于所有情况,但检查lambda的
\uuuu code\uuuu
属性会显示一个co\u name
属性,该属性恰好包含('x','y')
。不知道这是否足够。这实际上与lambda表达式没有任何关系。但如果您试图查看访问的属性,则始终可以使用打印其参数的\uu getattribute\uuuuu
方法定义自定义类:
class Something(object):
def __getattribute__(self, name):
print("{} was accessed".format(name))
如果现在将其传递给lambda表达式:
>>> l = lambda something: something.x > something.y
>>> s = Something()
>>> l(s)
x was accessed
y was accessed
注释后编辑它可能不适用于所有情况,但检查lambda的
\uuuu code\uuuu
属性会显示一个co\u name
属性,该属性恰好包含('x','y')
。不知道这是否足够。您可以访问反汇编字节码,尽管我认为这需要目视检查:
>>> import dis
>>> dis.dis((lambda something: something.x > something.y))
1 0 LOAD_FAST 0 (something)
3 LOAD_ATTR 0 (x)
6 LOAD_FAST 0 (something)
9 LOAD_ATTR 1 (y)
12 COMPARE_OP 4 (>)
15 RETURN_VALUE
>>>
您也可以通过编程方式执行此操作,效果如下:
>>> bc = dis.Bytecode(lambda something: something.x > something.y)
>>> for instr in bc:
... if instr.opname == "LOAD_ATTR":
... print(instr.argval)
...
x
y
>>>
您可以访问反汇编的字节码,尽管我认为这需要目视检查:
>>> import dis
>>> dis.dis((lambda something: something.x > something.y))
1 0 LOAD_FAST 0 (something)
3 LOAD_ATTR 0 (x)
6 LOAD_FAST 0 (something)
9 LOAD_ATTR 1 (y)
12 COMPARE_OP 4 (>)
15 RETURN_VALUE
>>>
您也可以通过编程方式执行此操作,效果如下:
>>> bc = dis.Bytecode(lambda something: something.x > something.y)
>>> for instr in bc:
... if instr.opname == "LOAD_ATTR":
... print(instr.argval)
...
x
y
>>>
我真的不明白你想做什么。你能给出一个具体的例子来解释吗?你想知道
x
和y
是从被称为something
的对象访问的,而不需要将代码传递给lambda函数吗?如果是这样,你可以尝试重写\uGetAttr\uuuu
方法d在类的定义中,something
是实例lambda something:print(something)或者某物.x>某物.y
是的,我正在研究访问对象x
和y
@inspectorG4dget查看我对Daniel Roseman的回答的评论,我试图在不实际执行的情况下获取引用。这可能是一个非常有趣的问题,但请编辑您的问题,使其更加清晰。我真的不明白你想做什么。你能给出一个具体的例子来解释吗?你想知道x
和y
是从被称为something
的对象访问的,而没有lambda函数的代码吗?如果是这样的话,你可以尝试重写\uGetAttr\uu
方法类定义中的od,其something
是实例lambda something:print(something)或者某物.x>某物.y
是的,我正在研究访问对象x
和y
@inspectorG4dget查看我对Daniel Roseman的回答的评论,我试图在不实际执行的情况下获取引用。这可能是一个非常有趣的问题,但请编辑您的问题,使其更加清晰。我曾想过这样做。但问题是lambda可能会有副作用(例如something.x.setValue(15)
),因此是一种非侵入性的方式(即不实际执行它)更好。@S.K.如果不调用lambda
,你怎么可能知道某物的身份呢?你真的需要用你要找的东西来澄清你的问题。@juanpa.arrivillaga@Daniel Roseman的答案基本上是解决问题的一半。我可以存储/更新/获取某物的列表我需要调用lambda
,它将执行代码。但在许多情况下,这可能会改变系统的状态。这能解释我的问题吗?我正在考虑使用一些解析方法,但我的python知识还不够好。如果lambda包含mult多个级别的引用(something.foo.spam.x
),例如,co_name
将每个元素作为一个单独的项包含在一起-没有关于它们是如何链接在一起的信息。我曾想过这样做。但问题是lambda可能有副作用(例如something.x.setValue(15)
),因此是一种非侵入性的方式(即不实际执行)更好。@S.K.如果不调用lambda
,你怎么可能知道某物的身份呢?你真的需要用你要找的东西来澄清你的问题。@juanpa.arrivillaga@Daniel Roseman的答案基本上是解决问题的一半。我可以存储/更新/获取某物的列表可以访问的
的元素。但是,为此,我需要调用
lambda来执行代码。但在许多情况下,这可能会改变系统的状态。这能解释我的问题吗?我正在考虑使用一些解析方法,但我的python知识还不够好。如果