如何命名在Python中返回值的函数?


13

我对在Python中为函数选择名称感到困惑。有时,Python内置函数势在必行,例如:printfunction和string method find。有时它们不是这样的:例如,len它的名称不是必须的calculate_len,而type不是find_type

我可以理解,它print返回了一个我们不使用的值(即None),并且执行了某项操作(即,它在屏幕上显示了一个字符串),因此其名称势在必行。

但是len返回一个我们使用并执行某项操作的值(即,计算序列或映射中有多少个项。),其名称不是必须的。另一方面,find字符串方法(as len)返回一个我们使用并执行某操作的值,并且它的名称是必要的

问这个问题的原因是,我将使用Caesar密码对字符串进行加密和解密的脚本进行了审查。审稿人说:

只是一种直觉:函数可以完成任务。因此,一个函数的好名字是势在必行的:我会用rotate_letter代替rotated_letter

rotated_letter返回表示由数字旋转的字母的单字母字符串。我不知道有什么更好的,我用rotated_letter它返回一个值,就像random模块中的randint function,不是。generate_randint

因此,在这种情况下,我应该如何命名一个返回要使用的值的函数?我应该将名称设为命令性还是仅是名词。在其他情况下,显而易见的是如何执行此操作,例如布尔函数,例如is_evenis_palindrome我们将其设为是/否问题,以及仅执行并返回未使用的值(即None)的函数,例如printand list方法。sort


这实际上是在命名函数时使用命令的一种非常普遍的做法(我会说一个约定)。例如,如何命名一个存储旋转函数的旋转字母的变量?
JoulinRouge '16

这不是思考您的一些示例的好方法。 len例如,最好将其视为“长度”-您将获得其参数的元级描述。
2016年

Answers:


10

在合理的范围内使用动词,如果名词简短且明确,则使用名词

大多数时候,函数应该是(命令式)动词,而类,变量和参数应该是名词。属性也应该是名词,包括使用创建的名词@property。对于具有副作用的功能尤其如此。[1] 如果某个函数确实返回了某些内容,则应评估该动词是添加内容还是仅仅是“噪声”:

  • make_list(foo)vs . list(foo):名词比动词更易读。另外,list实际上是一个类,而类应该是名词。
  • open(foo)vs . file(foo):动词比名词更易读,并且给动词赋予“ options”比给名词更有意义,因此在Python 3中名词被删除, open()仍然是唯一的“标准” [2]方式在Python 3中创建文件对象。
  • foo.get_bar()vs. foo.bar()vs. foo.bar(假设foobar都是名词):第一种选择是正确的,因为“ get”不会添加我们不知道的任何内容。如果bar退出fooa可能会导致昂贵的操作和/或带来副作用(您可能还会考虑Bar(foo)if是否Bar是一类),则第二种方法是合适的。如果这是一种廉价的操作且没有副作用,并且其他实现不太可能使其昂贵,则第三种方法是合适的。
  • xs.sort()vs. sorted(xs)if xs是一个列表:第一个必须要:对列表进行排序。它就地修改列表,不返回任何内容。第二个是声明性的:一个已排序的列表,正是它返回的内容。两者都是动词。

[1]:通常,返回值和具有副作用是互斥的,除非您出于某些令人信服的设计原因将它们组合在一起。因此,具有副作用的函数可能不应返回任何内容,因此将其设为名词将毫无意义。
[2]:模块中有一些中度较低的操作io,可用于添加或删除文件缓冲,自动文本编码/解码等,这些操作大多是名词,因为它们是面向对象的类。大多数用户不需要直接玩这些东西。而是open()选择一个合适的类并自动实例化。


谢谢!在foo.get_bar() vs. foo.bar()`vs. foo.bar”中第二个第三个之间有什么区别?
马哈茂德·穆罕默德·纳吉布

第三个是属性或裸属性。第二种是方法。
凯文

因此,据我了解,不要rotated_letter强制要求保持声明性,对吧?
马哈茂德·穆罕默德·纳吉布'16

在这种情况下,我不确定letter上下文是否暗含。
凯文

+1提的list是一类
杜尚MADAR

0

rotated_letter看起来不像一种方法。它看起来像一个属性。这意味着第一个想法是:

var letter = caesar.rotated_letter

期望letter包含字符串类型的值,而不是函数。从那里,您选择了另一个名称,例如:

def rotate_letter(self):
    pass

或者您改为使用属性:

@property
def rotated_letter(self):
    return self.whatever

lentype以此命名,因为其他任何名称都难以输入。它们使用很多,并且具有核心Python函数的特殊状态,每个Python程序员无论如何都会学到它们,这使得它们的名称比第三方库的名称更加无关紧要。

len尤其是,是你不应该在做一个很好的例子,你的代码:你预计使用全名,如length(除非短期形式非常流行,如max),并使用一个动词,如compute_length。或者它可能是一个属性:len([1, 5, 6])变为[1, 5, 6].length。例如,在C#中,使用后一种形式:new [] { ... }.Length

注意,有可能是由于历史的原因,以及为len:其它语言,如C#,优选的Count,这是通常的方法(虽然行为是不幸不一致通过.NET框架)。Count是动词,因此从直觉上讲,您倾向于将其作为一种方法来调用。

返回值或执行操作

总是期望某个功能执行一个动作。如果它几乎不返回值,则应为属性。您暗示在以下情况下应将该函数转换为属性:

  • 该函数几乎不包含一条return ...语句,

  • 函数名称很自然地出现在您的脑海中get_something,就像中的product.get_price()

现在,如果您有一个函数,它可以是以下四种类型之一:

  • 它可以是纯函数,即返回一个值而不影响环境。范例:road.measure_distance()

  • 它可以影响环境而不会返回任何东西。范例:product_database.remove_record(1234)

  • 它会影响环境并返回值。范例:value.increment()例如使用value++

  • 它什么也做不了,什么也不返回。范例:time.sleep(1)

在极少数情况下,名称可以提供有关函数类型的强烈提示,但在许多情况下,您将无法仅从名称中得知类型。


我认为答案是“是”,但是我必须问:您是否完全从Python的角度回答?因为在其他语言中,功能与属性的分离并不总是正确的。函数“必须执行动作”也不是正确的。这是Python中的约定吗?(我写的是Python,但还没有阅读所有PEP,而且我绝对不是专家。我并没有拒绝投票,BTW)。
Andres F.

@AndresF .:我是从Python的角度回答。在语言如Java,其属性是不存在的,getSomething而且setSomething是用来代替性能普通的名称。
阿森尼·穆尔坚科
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.