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

在Python中使用函数式编程的最佳实践!

发布时间:2019-01-28 05:46:12 所属栏目:建站 来源:菜鸟带你学编程
导读:简介 Python 是一种成果富厚的高级编程说话。它有通用的尺度库,支持多种编程说话范式,尚有很多内部的透明度。假如你乐意,还可以查察 Python 的底层并修改,乃至能在措施运行的时辰直接修改运行时。 我最近留意到一个有履历的 Python 措施员行使 Python

尚有很多高阶函数能用其他方法操纵函数,个中最值得一提的就是 partial,它能锁定函数的一部门参数。这种方法也叫做“currying”,这个术语来自函数式编程的先驱者 Haskell Curry:

  1. def power(base, exp):  
  2.  return base ** exp  
  3. cube = partial(power, exp=3)  
  4. cube(5) # returns 125 

关于 Python 中的 FP 观念的详细先容,以及奈何优先行使函数式举办编程,我保举 Mary Rose Cook 的这篇文章(https://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming)。

这些函数可以将很多行的轮回转酿成极其精简的一行代码。可是,一样平常的措施员也很难领略这些代码,出格是 Python 本来与英语异常相同的语法流。小我私人履历,我永久都记不住参数的次序,以及每个函数的成果,尽量我查了这么多次手册。但我凶猛提议实行一下这些函数,以相识一些 FP 的观念,并且偶然辰我以为它们才是正确的选择,如下一节的例子所示。

修饰器

高阶函数也以修饰器的情势融入了一般的 Python 编程中。界说修饰器的要领就反应了这一点,而@标纪录际上只是个语法糖,将被修饰的函数转达给修饰器作为参数。下面就界说了一个简朴的修饰器,它会将给定的代码重试三次,返回第一个乐成的值,可能在三次实行都失败之后放弃并抛出最后的非常。

  1. def retry(func):  
  2.  def retried_function(*args, **kwargs):  
  3.  exc = None  
  4.  for _ in range(3):  
  5.  try:  
  6.  return func(*args, **kwargs)  
  7.  except Exception as exc:  
  8.  print("Exception raised while calling %s with args:%s, kwargs: %s. Retrying" % (func, args, kwargs).  
  9.  raise exc  
  10.  return retried_function  
  11. @retry  
  12. def do_something_risky():  
  13.  ...  
  14. retried_function = retry(do_something_risky) # No need to use `@` 

这个修饰器的输入和输出的范例和值完全一样,但这并不是必需的。修饰器可以添加或镌汰参数,也可以改变参数的范例。它们也可以通过自己的参数举办设置。我想指出的是,修饰器自己不必然是“纯函数”,它们可以(并且常常会)有副浸染,只不外是刚巧行使了高阶函数罢了。

就像很多中级或高级 Python 能力一样,这个成果很是强盛,但也很轻易造成紊乱。你必需行使 functools.wrap 修饰器举办修饰,不然挪用的函数和栈跟踪中看到的函数名字会纷歧样。我见过一些修饰器会做一些很是伟大或很是重要的工作,如理会 json blob 中的值,可能处理赏罚认证。我还见过统一个函数或要领界说上的多层修饰器,必需把握修饰器的应用序次才气正确领略。我以为通过操作内置的修饰器如“staticmethod”可以辅佐领略,可能编写最简朴的修饰器来停止大量样板代码,但假如你想让你的代码切合范例搜查的话,那么只管不要去修改输入或输出的范例。

我的提议

函数式编程很风趣,并且进修舒服区之外的编程范式可以或许为你带来机动性,并且也可以让你从另一个角度思量题目。可是,我不保举行使 Python 时以函数式为主,出格是在旧的代码库中不要这么做。除了上面我提到的那些坑之外,尚有下面的来由:

  •  开始行使 Python 不必要领略 FP。这样做很也许会疑惑其他阅读者,可能疑惑将来的本身。
  •  你无法担保任何你依靠的代码(通过 pip 安装的模块,或其他同事的代码)是函数式的,是纯净的。你也不知道你本身的代码是否像你想象的那么纯净。与函数式为主的说话差异,Python 的语法或编译器不会帮你逼迫纯净,也不会帮你没落某些 Bug。将副浸染和高阶函数殽杂在一路回导致庞大的紊乱,由于你必要论证两种差异的伟大性,其难度是两者的乘积。
  •  行使带有范例注释的高阶函数是高级能力。范例署名凡是是又长又鸠拙的“Callable”的嵌套。譬喻,一个简朴的返回输入函数的高阶修饰器,其界说是“F = TypeVar[‘F’, bound=Callable[..., Any]]”,然后标注是“def transparent(func: F) -> F: return func”。大概你懒得研究正确的署名的写法,而直接行使“Any”取代了。

那么,我们应该行使函数式编程的哪部门呢?

纯函数

只要也许而且公道,就应该只管保持函数“纯净”,并细心思量该当在那里保持改变了的状态,并细心地标志好。这样能让单位测试变得更轻易,你不必要做太多 set-up 和 tear-down,也不必要太多 mocking,并且测试用例岂论执行次序怎样,城市发生预期中的功效。

下面是个非函数式的例子。

  1. dictionary = ['fox', 'boss', 'orange', 'toes', 'fairy', 'cup']  
  2. def puralize(words):  
  3.  for i in range(len(words)):  
  4.  word = words[i]  
  5.  if word.endswith('s') or word.endswith('x'):  
  6.  word += 'es'  
  7.  if word.endswith('y'):  
  8.  wordword = word[:-1] + 'ies'  
  9.  else:  
  10.  word += 's'  
  11.  words[i] = word  
  12. def test_pluralize():  
  13.  pluralize(dictionary)  
  14.  assert dictionary == ['foxes', 'bosses', 'oranges', 'toeses', 'fairies', 'cups'] 

(编辑:湖南网)

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

热点阅读