关于python:将函数放在类方法中是不是一个糟糕的编程实践?

Is it a bad programing practice to put a function inside a class method?

我在看这样一个案子:

1
2
3
4
5
6
7
8
9
10
11
def parse_item(self, response):

    item = MetrocItem()

    def ver(string):
        if string:
            return string
        else:
            return 'null'

    item['latitude'] = ver(response.xpath('//input[@id="latitude"]/@value').extract_first())

这是可行的,但有更好的方法吗?


正如注释中提到的@graipher,这在某些情况下确实有效,但在您的特定情况下,这是不必要的。如果函数依赖于局部变量,则返回每次调用该方法时都需要重新构造的闭包。但是在您的例子中,每次调用方法时,函数的行为都是一样的,因此将它全局定义为私有方法,甚至在您的例子中定义为lambda更为合理。

1
ver = lambda x: x if x else 'null'

但最好的方法是简单地在全球范围内定义它,并在名称的开头加上下划线,以明确其意图。

1
2
def _ver(string):
    ...


你可以完全摆脱这个功能:

1
2
string = response.xpath('//input[@id="latitude"]/@value').extract_first()
item['latitude'] = string if string else 'null'


这不是坏的做法,但这里有一个选择。

由于这个小函数不依赖于parse_item中的任何内容,您可能希望它只构造一次,为了提高性能,您可以这样做:

1
2
3
4
5
6
7
8
def parse_item(self, response):
    ...

def _ver(string):
    ...

parse_item.ver = _ver
del _ver

parse_item中称之为parse_item.ver而不仅仅是ver。这样就避免了混乱的全局名称空间,即使使用了Python为您部分隐藏的带下划线的方法。

我本可以推荐lambda表达式作为另一种选择,但席尔维奥先做到了。

此外,所有人都能看到它可能是一个全局函数的评论,只有当它有可能在其他地方使用时才有意义。

同样,你也可以完全消除这个例子,正如DoctorLove和Niklas所建议的那样,但是我假设你的意思是说,这是一个更复杂的例子。


有一些具有局部函数的用例——要么在类方法中,要么在其他方法中,比如说如果您想要一个捕获局部内容的闭包。

在这种情况下,您需要类似colasecing null的内容:

例如

1
2
3
>>> s = None
>>> s or"None"
'None'

所以,你可以使用

1
item['latitude'] = response.xpath('//input[@id="latitude"]@value').extract_first() or"null"

我想parse_item是您类中的一个方法。然后,您可以使用Python的"私有"方法来提高代码的可读性和简洁性。检查如何编写python"private"方法,然后检查为什么它实际上不是私有方法。;)