函数列表Python

时间:2018-01-19 10:11:56

标签: python python-3.x list function reference

我有一个模式列表:

    patterns_trees = [response.css("#Header").xpath("//a/img/@src"), 
                      response.css("#HEADER").xpath("//a/img/@src"),
                      response.xpath("//header//a/img/@src"),
                      response.xpath("//a[@href='"+response.url+'/'+"']/img/@src"),
                      response.xpath("//a[@href='/']/img/@src")
                      ]

在遍历它并找到正确的模式后,我必须将模式作为参数发送给回调函数

for pattern_tree in patterns_trees:
...
    pattern_response = scrapy.Request(...,..., meta={"pattern_tree": pattern_tree.extract_first()})

通过这样做,我得到正则表达式的值而不是模式

我试过的事情:

我尝试在一个单独的类中隔离模式,但我仍然遇到的问题是我不能将它们存储为模式而是存储为值。

我试图将它们保存为字符串,也许我可以使它工作但

存储功能列表的最有效方法是什么

更新:可能的解决方案,但过于难以编码,当我想添加更多模式时,它会出现问题:

def patter_0(response):
    response.css("#Header").xpath("//a/img/@src")    
def patter_1(response):
    response.css("#HEADER").xpath("//a/img/@src")
.....
class patternTrees:
    patterns = [patter_0,...,patter_n]

    def length_patterns(self):
        return len(patterns)

2 个答案:

答案 0 :(得分:2)

如果您愿意考虑重新格式化您的操作列表,那么这是一个有点简洁的解决方案。我已将操作列表更改为元组列表。每个元组包含(一个ref)相应的函数,另一个元组由参数组成。

将新操作添加到列表中相当容易:只需指定要使用的函数和相应的参数即可。

如果要在下一个操作中将一个操作的结果用作参数:您必须从 execute()返回值并在 for循环中处理它

我已使用 prints()替换了对响应的调用,以便您可以轻松地进行测试。

def response_css_ARG_xpath_ARG(args):
    return "response.css(\"%s\").xpath(\"%s\")" % (args[0],args[1])
    #return response.css(args[0]).xpath(args[1])

def response_xpath_ARG(arg):
    return "return respons.xpath(\"%s\")" % (arg)
    #return response.xpath(arg)

def execute(function, args):
    response = function(args)
    # do whatever with response
    return response 

response_url = "https://whatever.com"


patterns_trees = [(response_css_ARG_xpath_ARG, ("#Header", "//a/img/@src")), 
                  (response_css_ARG_xpath_ARG, ("#HEADER", "//a/img/@src")),
                  (response_xpath_ARG, ("//header//a/img/@src")),
                  (response_xpath_ARG, ("//a[@href='"+response_url+"/"+"']/img/@src")),
                  (response_xpath_ARG, ("//a[@href='/']/img/@src"))]

for pattern_tree in patterns_trees:
    print(execute(pattern_tree[0], pattern_tree[1]))

请注意, execute()可以省略!取决于您是否需要处理结果。如果没有执行程序,您可以直接从循环中调用该函数:

for pattern_tree in patterns_trees:
    print(pattern_tree[0](pattern_tree[1]))

答案 1 :(得分:0)

我不确定我是否理解您要做的事情,但是您可以将列表列为lambda函数列表,如下所示:

patterns_trees = [
    lambda response : response.css("#Header").xpath("//a/img/@src"),
    ...
]

然后,在你的循环中:

for pattern_tree in patterns_trees:
    intermediate_response = scrapy.Request(...)  # without meta kwarg
    pattern_response = pattern_tree(intermediate_response)

或者离开meta会对response对象产生影响吗?