对于可以返回已修改对象或仅修改实例的函数,Python 中的命名约定是什么。
假设你想同时实现这两个,你应该如何命名函数?
示例:假设您想要一个crop()
Image 对象的函数。我 Ruby 它很简单,因为crop()
如果您返回副本并crop!()
修改原始实例,您应该使用它。
对于可以返回已修改对象或仅修改实例的函数,Python 中的命名约定是什么。
假设你想同时实现这两个,你应该如何命名函数?
示例:假设您想要一个crop()
Image 对象的函数。我 Ruby 它很简单,因为crop()
如果您返回副本并crop!()
修改原始实例,您应该使用它。
不确定某些 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 中,两者之间的区别纯粹是传统的(函数/方法行为独立于你如何调用它)。
!
在标准库中,有类似list.sort()
and之类的方法list.reverse()
可以修改list
原位,以及类似sorted()
and的函数reversed()
返回一些新的东西(reversed()
返回一个迭代器而不是一个新列表)。但如果实例方法比函数更有意义,我不会仅仅为了保持这个约定而这样做。
在 NumPy 中,许多函数和方法都有一个out
关键字参数,允许您指定输出应该转到现有数组而不是创建新数组。您甚至可以使out
数组成为输入数组之一。
此 AFAIK 没有“Python 范围”的约定。但是,我从事的一个项目有一个可能对您有用的约定:如果一个函数可以就地修改其参数,它有一个copy
kwarg 来确定它是否对其输入的副本进行操作,并且默认为True
.
def crop(x, copy=True):
if copy:
x = x.copy()
_do_inplace_crop(x)
return x
如果我想修改一些东西,我会写一个方法:
smth.crop()
如果我希望它返回一个修改后的对象,那么我会使用一个函数:
crop(smth)
这样你就可以保持函数式的函数(没有副作用),以及 OOP 风格的方法(有副作用)。
但是,我也希望 Python 允许在函数名称!
中使用?
字符,如 Ruby 和 Lisp。