lambda表达式,从具有多个形参的列表中返回函数名



我需要做一个lambda表达式,从一个有多个参数的列表返回函数的名称,我写了下面的代码,但不是给我函数的名称,它返回这个<函数funB在0x01FDBE80>我该怎么修理它?

def funA():
pass
def funB(a):
pass
def funC(a, b):
pass
n = [funA, funB, funC]
m = list(filter(lambda x: x.__name__ if x.__code__.co_argcount > 0 else None, n))
print(m)

问题是filter使用函数,它是作为一个布尔谓词纯粹用于过滤,而不是用于改变产生值。

在本例中,它将把x.__name__ if x.__code__.co_argcount > 0 else NoneTrue的所有函数添加到生成的生成器中,但它将按原样添加函数对象本身,而不是其.__name__属性。

From the docs:

从iterable中返回true的元素构造一个迭代器。Iterable可以是序列、支持迭代的容器或迭代器。如果function为None,则假定为恒等函数,即删除iterable中所有为false的元素。注意,如果function不为None, filter(function, iterable)等价于生成器表达式(item for item in iterable,如果function(item));如果function为None,则等价于(item for item in iterable,如果item)。

这就是为什么

m = list(filter(lambda x: x.__code__.co_argcount > 0, n))

将给出与当前代码相同的输出。

在这种情况下你不应该使用filter:

m = list(f.__name__ for f in n if f.__code__.co_argcount > 0)

为了避免这样的副作用,只需添加进一步的步骤(参见DeepSpace的解释),使用map过滤并检索名称(根据需要)。

fs = [funA, funB, funC]
fs_filtered = map(lambda f: f.__name__, filter(lambda f: f if f.__code__.co_argcount > 0 else None , fs))
print(list(fs_filtered))

或更好:

fs_filtered  = filter(None, map(lambda f: f.__name__ if f.__code__.co_argcount > 0 else None, fs))
print(list(fs_filtered ))

Appendum:filter仅用于过滤器,不支持对迭代器项的操作。在这个例子中,print工作得很好,但是.__name__

末尾被忽略了。
m = list(filter(lambda f: (print(f.__name__), f.__name__)[1] if f.__code__.co_argcount > 0 else None, fs))
# funB
# funC
# [<function funB at 0x7f6337eeddc0>, <function funC at 0x7f6337eede50>]

相关内容

  • 没有找到相关文章

最新更新