6

对于可以返回已修改对象或仅修改实例的函数,Python 中的命名约定是什么。

假设你想同时实现这两个,你应该如何命名函数?

示例:假设您想要一个crop()Image 对象的函数。我 Ruby 它很简单,因为crop()如果您返回副本并crop!()修改原始实例,您应该使用它。

4

4 回答 4

5

不确定某些 PEP 中是否有精确的指导方针,但看看某些函数/方法在 python 核心中的工作方式,我个人使用动词共轭。例如,灵感来自:

>>> l = list('hello world')
>>> l
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> sorted(l)
[' ', 'd', 'e', 'h', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> l
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> l.sort()
>>> l
[' ', 'd', 'e', 'h', 'l', 'l', 'l', 'o', 'o', 'r', 'w']

我会命名您的函数crop()[就地修改对象] 和cropped()[返回修改后的副本]。

编辑:我不知道 ruby​​,但在 python 中,两者之间的区别纯粹是传统的(函数/方法行为独立于你如何调用它)。

于 2011-11-21T12:40:58.220 回答
2

在标准库中,有类似list.sort()and之类的方法list.reverse()可以修改list原位,以及类似sorted()and的函数reversed()返回一些新的东西(reversed()返回一个迭代器而不是一个新列表)。但如果实例方法比函数更有意义,我不会仅仅为了保持这个约定而这样做。

在 NumPy 中,许多函数和方法都有一个out关键字参数,允许您指定输出应该转到现有数组而不是创建新数组。您甚至可以使out数组成为输入数组之一。

于 2011-11-21T12:45:11.133 回答
1

此 AFAIK 没有“Python 范围”的约定。但是,我从事的一个项目有一个可能对您有用的约定:如果一个函数可以就地修改其参数,它有一个copykwarg 来确定它是否对其输入的副本进行操作,并且默认为True.

def crop(x, copy=True):
    if copy:
        x = x.copy()
    _do_inplace_crop(x)
    return x
于 2011-11-21T12:41:07.897 回答
0

如果我想修改一些东西,我会写一个方法:

smth.crop()

如果我希望它返回一个修改后的对象,那么我会使用一个函数:

crop(smth)

这样你就可以保持函数式的函数(没有副作用),以及 OOP 风格的方法(有副作用)。

但是,我也希望 Python 允许在函数名称!中使用?字符,如 Ruby 和 Lisp。

于 2011-11-21T12:47:29.960 回答