金华市,改动代码又不损坏它,运用装修器吧,7zip

怎么从了解一个功用到运用它来处理问题?

答案是把它用在对个人影响小且不重要的项目中。阅览这样的文章或许也会有所协助。

我最近开端在Nilearn(http://nilearn.github.io/)和Nistats(http://nistats.github.io/)担任Python开发人员,这两个库是神经科学中用于剖析功用性MRI数据的开源Python库。

在兼并了Nilearn中最近的一个推送恳求(pull-requ长沙银行心意通卡est)之后,我意识到,为像我这样的新开发人员编写整个进程的文档对错常有用的,由于他们在之前的作业中没有编写过商业代码。

我决议追溯和重构我其时的进程和主意,鲷增加代码和文原本阐明它们。这有一个不幸的副作用,即细节的深度只取决于我的记忆力,而实践的代码示例只来历于我提交过的代码。其间也会有一些代码示例,是我从来没有提交过或许从来没有写过的,只是在我的脑海中把它们看作是或许的。

这并不影响这篇文章的实用性序列号。

留意,我(终究)运用了decorator和**kwargs,但并没有解说这些,由于这不是我写这篇文章的意图,网上有许多教程能够协助您了解这两个概念。

此外,柒这些库现在是Python2兼容的,金华市,改动代码又不损坏它,运用装修器吧,7zip所以有时咱们的挑选或许会遭到一些约束。

也便是说,Geronimo(不要怕,一往无前)!

序文

这是咱们库中的函数。为了简练,我删除了文档字符串,这个功用对这篇文章来说并不重要:


咱们的使命是使view_connectomeexist()与库中另一个较老的函数plot_connectome()保持一致。咱们期望它们有相同的函数签名。

为什么?一致性,假如处理妥当和合理,能够使函数易于运用。本质上,一旦用户了解了咱们的一个<>_connectome() 函数,他们就知道怎么调用所金华市,改动代码又不损坏它,运用装修器吧,7zip有函数。

咱们想改动函数签名中某些参数的称号:

coords>node_coords

cmap>edge_camp

threshold>edge_threshold

marker_size>node_size

不运用迭代:

假如我是这个库的仅有用阑鬼坊户,那么改动它就十分简略:

重命名函数签名中的参数,重命名函数体中的变量,对文档字符进行恰当改动,等等…

叮咚~!完结了!

还金华市,改动代码又不损坏它,运用装修器吧,7zip没有。

留意事项:

我并不是这个库的仅有运用者。假如我以这种办法进行更改,那么假如其他用户运用关键字参数时(他们应该会这样做),就会损坏他们的现有代码。

请留意,我蓁并没有处处更改称号,只更改了参数和相关变量。我没有在inconnectome_info["mark耿富有er_size"]=node_size爱情游戏中更改键称号,也没有在_get_connectome()中更改cmap参数。

这是由于:

  1. 这并不是PR(pull-request,推送恳求)所要做的,而PR应该尽或许紧凑,以便于查看、盯梢、调试和查看更改。任何额定的问题或潜在的改善或代码整理都是一个新问题,一个新PR,能够一起提交,并与当时PR分隔。

  2. 改动其他任何工作都或许引发一些下流需求处理的问题。

  3. _get_connectome()是Python中的一个私有函数,而不是面向用户的函数,因而对它进行更改关于用户界面的影响要简略得多。

咱们需求做的是找到一个办法去:

  1. 保证方位参数不损坏。

  2. 让参数的新称号和旧称号一起作业。

  3. 在此转化阶段向用户显现弃用正告。

关于Nilearn,这个过渡期一般意味着2个版别(大约8-11个月),包含point/minor版别。

上述完结只满意第一个考虑(1.保证方位参数不被损坏。)

第一次迭代

这很简单做到。

咱们用新的参数替换本来的参数以保存方位参数,然后在结尾增加替换的参数,这样旧的关键字参数依然能够作业。

然后,咱们在函数体中增加代码,用于将args提交给新参数并生成恰当的弃用正告。

好吧,这行得通,可是,李教授抗寒蚊子被判刑金华市,改动代码又不损坏它,运用装修器吧,7zip天哪!这看起来是不是不简练仍是什么?!

我把代码变得更长、更难红酒怎么喝以阅览、更丑陋,并且函数表现在要做的不仅仅是一件事:解析和处理参数以及它开始要做的工作。

为了简练起见,我成心省掉了这儿的warn沈曼ing .filter()部分DeprecationWarnings默许情况下是不向终端用户显现的)。

第2次迭代

我决议将具体正告部分重构为私有函数,并从主体野间安娜函数中调用它。

这样好多了。我是这样看待它的:

  1. 增加到原始函数的代码行数更少。

  2. 更简单编写单元测验来查看引发的正告。

  3. 函数签名的改动几乎不超越最小必要性。

和…

  1. 尽管如此,仍是必须在原始函数中增加几行代码。

  2. 没有单元测验来测验值从旧参数到新参数的正确切换。

  3. 函数签名的改动超出了最小必要性。

第三次迭代

由于本质上我想做的是修正现有函数的行为,或许润饰它,所以我决议运用Python的decorator特性来完结这项使命。

所以我写了一个。


这样就好多了!

我底子不需求改动函数体,函数签名的改动对我来说也是能够承受的。除了更改参数称号外,只在函数签名中增加了**kwargs。

当彻底移除这个正告的时分,本来的函数就完金华市,改动代码又不损坏它,运用装修器吧,7zip全不需求修正了。

我增加了一个测验(我以为这是一个集成测验,但语义对这篇文章来说并不重要,在我看来。IMO,in my opinion)。

我以为便是这样,短发卷发并且这很好。

第四次钟炳浩迭代

成果几周后,我不得不对Nilearn中的另一个函数做相同的工作,它的一组参数需求更改,这样一来,Nistats中的三个不同函数也需求更改相同的参数。

这时,我决议将它变成一个通用的运用函数,经过让decorator承受参数来完结。

犹疑了一会之后,我决议重用我即将为Nilearn编写的代码,以便在Nistats中完结相同的意图,由于duh,并且在不久的将来,咱们还要把Nist金华市,改动代码又不损坏它,运用装修器吧,7zipats库兼并到Nilearn中,所以这样做很好。

咱们没有去寻觅一个或许现已完结这些的外部库,由于:

  1. 不到万不得已,咱们不想在代码中引进过多的依靠联系。

  2. 咱们不想为了一个小功用去装置一个库。

  3. 一般来说,较小的金华市,改动代码又不损坏它,运用装修器吧,7zip(较少运用/盛行的)库或许更简单中止保护。我没有寻觅任何数据来支撑这一点,但对我来说好像很有含义。

  4. 一般来说,Nilearn & Nistats库的许多外部奉献者都是从事代码开发的科学家,尽管他们都对错常优异的程序员,可是在混合时引进新事物和库会增加奉献妨碍。

出于这个意图,我决议创立一个名为replace_parameters的通用装修器,并将其增加到ni火腿肠learn/_utils/helper.py模块中。

下面是终究的代码:

现在我是否有必要为这儿的私有函数编写额定的文档字符串呢?有些人或许会说没必要,但我觉得有必要。

  1. 内部/私有函数的具体文档字符串有助于下一个参加团队的开发人员了解代码根底,特别是当原作者或许不在时。

  2. 它使我更简单编写单元测验,由于我知道预期成果是什么。文档字符串在我的脑海中列出了这一切。

首要函数是这样的:

Woohoo(哇偶)!

  1. 除了咱们要重命名的东西外,函数体无需更改。

  2. 函数签名不需求更改,只需求从头命狂野飙车名咱们计划重命名的参数。事实证明,运用decorator之后,我不需求显式声明**kwargs。

  3. 该功用易于重用、整理和测验。

我决议保存我现已写好的集成测验,并为这段新代码增加单元和集成测验。


这便是我处理这个问题的进程,其实也是一步一步的考虑让我找到了处理方案。

我在这儿增加了终究的代码和测验作为一个gist (Generalized Search Trees,通用查找树):

https://gist平坝气候.github.com/kchawla-pi/40a08a18dc04f39cd338a4cdc15eb6


英文原文:https://dev.to/kchawla_pi/using-a-decorators-to-solve-my-task-the-thm37y30inking--the-process-49f0  

译者:天天向上