返回动态创建的函数

ano*_*ato 2 python lambda beautifulsoup

我正在尝试创建一个带有多个参数的函数,并返回一个可调用的lambda函数.我将这些lambda函数传递给BeautifulSoup的find_all方法以解析html.

这是我为生成lambda函数而编写的函数:

def tag_filter_function(self, name="", search_terms={}, attrs=[], **kwargs):

    # filter attrs that are in the search_terms keys out of attrs
    attrs = [attr for attr in attrs if attr not in search_terms.keys()]

    # array of strings to compile into a lambda function
    exec_strings = []

    # add name search into exec_strings
    if len(name) > 0:
        tag_search_name = "tag.name == \"{}\"".format(name)
        exec_strings.append(tag_search_name)

    # add generic search terms into exec_strings
    if len(search_terms) > 0:
        tag_search_terms = ' and '.join(["tag.has_attr(\"{}\") and tag[\"{}\"] == \"{}\"".format(k, k, v) for k, v in search_terms.items()])
        exec_strings.append(tag_search_terms)

    # add generic has_attr calls into exec_strings
    if len(attrs) > 0:
        tag_search_attrs = ' and '.join(["tag.has_attr(\"{}\")".format(item) for item in attrs])
        exec_strings.append(tag_search_attrs)

    # function string
    exec_string = "lambda tag: " + " and ".join(exec_strings)

    return exec(compile(exec_string, '<string>', 'exec'))
Run Code Online (Sandbox Code Playgroud)

从调用返回的函数字符串

tag_filter_function(name="article", search_terms={"id" : "article"})
Run Code Online (Sandbox Code Playgroud)

lambda tag: tag.name == "article" and tag.has_attr("id") and tag["id"] == "article"
Run Code Online (Sandbox Code Playgroud)

函数的返回值是None.我不相信这个exec()功能是我想在这里使用的,但我真的不确定.是否可以将此字符串转换为可执行的lambda函数,如果是这样的话?不确定我是否以正确的方式进行此操作.

zvo*_*one 5

绝对没有必要使用exec.要从函数返回函数,只需定义一个新函数并将其返回.例如

def outer_function():
    def inner_function():
        something_here
    return inner_function
Run Code Online (Sandbox Code Playgroud)

在你的情况下,看起来你想做这样的事情:

def tag_filter_function(self, name="", search_terms={}, attrs=[], **kwargs):

    # filter attrs that are in the search_terms keys out of attrs
    attrs = [attr for attr in attrs if attr not in search_terms.keys()]

    def f(tag):

        # add name search into exec_strings
        if len(name) > 0:
            if tag.name != name:
                return False

        # add generic search terms into exec_strings
        if len(search_terms) > 0:
            if not all(tag.has_attr(k) and tag[k] == v
                   for k, v in search_terms.items()):
                return False

        # add generic has_attr calls into exec_strings
        if len(attrs) > 0:
            if not all(tag.has_attr(item) for item in attrs):
                return False

        return True

    return f
Run Code Online (Sandbox Code Playgroud)

  • 人们有不同的偏好,但我认为`functools.partial`比嵌套函数更有效. (2认同)