加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

怎样写一个更好的Python函数?

发布时间:2018-10-18 01:08:17 所属栏目:大数据 来源:量子位
导读:Python固然好用,但用好真的很难。 尤其是函数部门,只要写欠好,后头的陆续串人城市遭殃。 看又看不懂,测试起来也贫困,维护又维护不动,真是让人头疼。 那怎么写好一个Python函数呢? 《Writing Idiomatic Python》一书的作者在Medium上颁发了一篇文章
副问题[/!--empirenews.page--]

Python固然好用,但用好真的很难。

尤其是函数部门,只要写欠好,后头的陆续串人城市遭殃。

看又看不懂,测试起来也贫困,维护又维护不动,真是让人头疼。

那怎么写好一个Python函数呢?

500523822_wx

《Writing Idiomatic Python》一书的作者在Medium上颁发了一篇文章,给出了6个提议。

但愿可以或许给你带来辅佐。

什么样的函数是一个好函数?

“好”的Python函数和“差”的Python函数之间有什么不同呢?每小我私人都有本身的领略。基于我的领略,假如一个Python函数可以或许切合下面的大部门前提,我会以为它是一个“好”函数:

定名公道

单一成果

包罗文档字符串

返回一个值

不高出50行

是幂等函数或纯函数

对很多人来说,这些要求也许显得过于苛刻了。

不外,我担保,假如你的函数遵循这些法则,你的代码会很是大度,会让其他的措施员都“馋哭”的。

下面,我将逐一接头这些法则,然后总结它们是怎样缔造“好”函数的。

定名

在这个题目上,我最喜好的一句话是:

计较机科学中只有两件事很让人头疼:缓存失效和定名。

尽量这听起来很莫名其妙,但给一个工作定名太难了。下面是一个后面案例:

defgetknn(from_df):

原文中这个代码没有放上去,量子位按照上下文信息举办了增补。

这个函数定名的第一个题目是它行使了缩写。

对付那些并不着名的缩略词来说,行使完备的英语单词会更好。缩写单词的独一缘故起因是为了节减打字时刻,可是每个当代编辑器都有自动添补成果,以是你只必要键入一次全名就可以了。

缩写凡是是特定规模的。在上面的代码中,KNN指的是“K-Nearest Neighbors”,df指的是“DataFrame”,这是一个数据布局。假如另一个不认识这些首字母缩写的措施员正在阅读代码,险些很丢脸懂。

关于这个函数的名字尚有其它两个小瑕疵:

“get”这个词是无关紧急的。对付大大都定名较量好的函数来说,很明明有一些对象会从函数中返回,它的名字将反应这一点。

from_df也不是须要的。假如没有明晰的参数名称,函数的文档字符串或范例注释会描写参数的范例。

那么我们怎样重定名这个函数呢?很简朴:

defk_nearest_neighbors(dataframe):

纵然是生手,这个函数要计较的内容也很清晰,参数的名称(dataframe)也清晰地表白了参数范例。

单一成果

单一成果原则不只合用于类和模块,也同样合用于函数。

一个函数应该只有一个成果。也就是说,它应该只做一件事。

一个重要的缘故起因是,假如每个函数只做一件事,只有这件事产生了变革,才必要改变这个函数。

另外,假如这个函数的单个成果不再必要了,直接把它删了就行了。

照旧用例子来声名吧。下面这个函数,可以做不止一件“工作”:

defcalculate_andprint_stats(list_of_numbers):

sum = sum(list_of_numbers)

mean = statistics.mean(list_of_numbers)

median = statistics.median(list_of_numbers)

mode = statistics.mode(list_of_numbers)

print('-----------------Stats-----------------')

print('SUM: {}'.format(sum) print('MEAN: {}'.format(mean)

print('MEDIAN: {}'.format(median)

print('MODE: {}'.format(mode)

这个函数做了两件事:一是计较一组关于数字列表的统计数据,二是将它们打印到STDOUT。

假如必要计较新的或差异的统计数据,可能必要改变输出的名目,就必要对这个函数举办调解。

以是,这个函数最好写成两个独立的函数:一个用来执行并返回计较功效,另一个用来获取这些功效并打印出来。

这种处理赏罚方法,不只能让测试函数更轻易,而且还应承这两个部门有了迁徙性,假如吻合的话,还也许一路应用到差异的模块中。

在编程中,你会发明许多几何函数都可以做许多许多工作。同样,为了可读性和可测试性,这些函数应该被解析成更小的函数,每个函数只有一个成果。

文档字符串(Docstrings)

固然每小我私人好像都知道PEP - 8,它界说了Python的样式指南,可是很少有人知道PEP - 257,它是关于文档字符串的。我再这里不简朴地一再PEP - 257的内容了,你可以在闲暇时读一下。个中的要害内容是:

每个函数都必要有一个文档字符串

行使恰当的语法和标点标记;用完备的句子写

起首对函数的浸染举办一句话的总结

行使声名性说话而不是描写性说话

在编写函数时,要养成写文档字符串的风俗,并在编写函数代码之前实行写一下。

假如你不能写一个清楚的文档字符串来描写函数做什么,就声名你必要再思量思量为什么要写这个函数了。

返回值

函数可以被以为是一些独立的措施。它们以参数的情势接管一些输入,并返回一些功效。

参数有没有都可以,但从Python内部的角度来看,返回值是必必要有的。你不行能建设一个没有返回值的函数。假如函数没有返回值,Python会“逼迫”返回None。你可以测试一下这段代码:

? python3

Python3.7.0(default, Jul232018,20:22:55)

[Clang9.1.0(clang-902.0.39.2)] on darwin

Type"help","copyright","credits"or"license"formore information.

>>>defadd(a, b):

... print(a + b)

...

>>> b = add(1,2)

3

>>> b

>>> bisNone

True

你会发明 b 的返回值现实上是 None。 纵然你写的函数没有返回语句,它如故会返回一些对象。并且,每个函数都应该返回一个有效的值,测试起来也会更利便。事实,你写的代码应该可以或许被测试。

试想一下,测试上面的add函会有多艰巨。遵循这个观念,我们应该这样写代码:

withopen('foo.txt','r')asinput_file:

forlineininput_file:

ifline.strip().lower().endswith('cat'):

# ... do something useful with these lines

if line.strip().lower().endswith(‘cat’):这一行可以或许事变,是由于每个字符串要领( strip ( )、lower ( )、end swith ( ) )都返回一个字符串作为挪用函数的功效。

当给定函数没有返回值时,有一些常见的缘故起因:

“它所做的只是[一些与I / O相干的工作,好比将一个值生涯到数据库中]。我不能返回任何有效的对象。”

我差异意。假如操纵顺遂完成,函数可以返回True。

“我们修改了个中一个参数,将其用作参考参数。”

这里有两点必要留意。起首,尽最大全力停止这种做法。用好了令人惊奇,用欠好很是伤害。

其次,纵然这样做不行行,复制某个参数的本钱太高,你也可以回到上一条提议。

“我必要返回多个值。单独返回一个值是没故意义的。”

可以行使元组返回多个值。

老是返回一个有效的值,挪用者老是可以自由地忽略它们。

函数长度

让你读一个200行的函数,并说出它是做什么的,你是什么感觉?

函数的长度直接影响可读性,从而影响可维护性。以是要保持你的函数简短。50行是一个随意的数字,在我看来是公道的。你编写的大大都函数应该要短一些。

假如一个函数遵循单一成果原则,它很也许是相等短的。 假如它是纯函数或是幂等的(下面接头) ,它也也许是短的。

那么,假如函数太长,应该怎么做?重构。这会改变措施的布局而不改变其举动。

从一个长函数中提取几行代码,并把它们酿本钱身的函数。这是收缩长函数的最快、也是最常见的方法。

加上你给全部这些新函数取了吻合的名称,因今天生的代码读起来也会更轻易。

幂等和函数纯度

不管被挪用了几多次,幂等函数老是在给定沟通参数集的环境下返回沟通的值。

功效不依靠于非局部变量、参数的可变性或来自任何I / O流的数据。下面的这个add_three(number)函数是幂等函数:

不管一小我私人挪用add_three(7)几多次,谜底老是10。以下是一个非幂等函数:

defadd_three():

"""Return 3 + the number entered by the user."""

number = int(input('Enter a number: '))

returnnumber +3

这个函数的返回值取决于I / O,即用户输入的数字。对add_three()的每次挪用城市返回差异的值。

假如它被挪用两次,用户可以第一次输入3,第二次输入7,别离挪用add_three()返回6和10。

幂等性的一个实际中例子是在电梯前点击“向上”按钮。第一次定时,电梯会被“关照”你要上去。由于按按钮是幂等的,以是重复按它都没有什么影响。功效是一样的。

为什么幂等很重要?

可维护性和可维护性。幂等函数很轻易测试,由于在行使沟通的参数时,它们老是返回沟通的功效。

测试仅仅是搜查通过差异挪用返回值的预期值。更重要的是,这些测试很快,这是单位测试中一个重要且常常被忽视的题目。

而在处理赏罚幂等函数时,重构是垂手可得的工作。 无论如安在函数之外变动代码,行使沟通的参数挪用它的功效老是一样的。

什么是纯函数?

在函数编程中,假如一个函数既幂等又没有可调查到的副浸染,它就被以为是纯函数。函数外部的任何对象都不会影响这个值。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读