“导入模块"是否比“从模块导入功能"更好的编码风格? [英] Is `import module` better coding style than `from module import function`?
问题描述
让from module import function
称为FMIF编码风格.
让import module
称为IM编码风格.
让 from package import module
称为 FPIM 编码风格.
为什么 IM+FPIM 被认为是比 FMIF 更好的编码风格?(参见这篇文章这个问题的灵感.)
以下是一些让我更喜欢 FMIF 而非 IM 的标准:
- 代码简短:它允许我使用较短的函数名称,从而有助于坚持每行 80 列的约定.
- 可读性:
chisquare(...)
看起来比scipy.stats.stats.chisquare(...)
更具可读性.虽然这是一个主观标准,但我想大多数人都会同意. - 易于重定向:如果我使用 FMIF 并且稍后出于某种原因想要重定向 python 以从
alt_module
而不是module
定义function
code> 我只需要更改一行:from alt_module import function
.如果我要使用 IM,我需要更改多行代码.
我对 IM+FPIM 可能比 FMIF 更好的所有原因感兴趣,但特别是,我有兴趣详细说明以下几点 此处提及:
IM 的优点:
- 易于在测试中模拟/注入.(我对模拟不是很熟悉,尽管我最近了解了这个术语的含义.你能在这里展示代码来证明 IM 比 FMIF 更好吗?)
- 模块通过重新定义一些条目来灵活改变的能力.(我一定是误解了一些东西,因为这似乎是 FMIF 相对于 IM 的优势.请参阅上面我支持 FMIF 的第三个原因.)
- 数据序列化和恢复的可预测和可控行为.(我真的不明白选择IM还是FMIF对这个问题有什么影响.请详细说明.)
- 我知道 FMIF污染了我的命名空间",但除了听起来消极的短语之外,我不明白这如何以任何具体方式损害代码.
非常感谢.
您为 IM/FPIM 列出的否定通常可以通过适当使用 as
子句来改善.from some.package import mymodulewithalongname as mymod
可以有效地缩短您的代码并增强其可读性,如果明天将 mymodulewithalongname
重命名为 somethingcompletelydifferent
,as
子句可以作为单个语句进行编辑.
考虑您的亲 FMIF 点 3(称其为 R 表示重定向)与您的亲 FPIM 点 2(称其为 F 表示灵活性):R 相当于促进模块边界完整性的丧失,而 F 则加强了它.一个模块中的多个函数、类和变量通常旨在协同工作:它们不应独立切换为不同的含义.例如,考虑模块 random
及其函数 seed
和 uniform
:如果您将其中一个的导入切换到不同的模块,那么您将中断对 seed
的调用和对 uniform
的调用结果之间的正常连接.当一个模块设计良好,具有内聚性和完整性时,R 对打破模块边界的促进实际上是负面的——它使你更容易做一些你最好不做的事情.>
反之亦然,F 使协调耦合函数、类和变量(因此,通常,通过模块化属于属于的实体)能够协调切换.例如,为了使测试具有可重复性(FPIM pro-point 1),您可以在 random
模块中模拟 seed
和 random
,并且如果您的代码遵循FPIM,一切就绪,协调保证;但是如果你有直接导入函数的代码,你必须寻找每个这样的模块并一遍又一遍地重复模拟.使测试完全可重复通常还需要对日期和时间函数进行协调模拟"——如果您在某些模块中使用 from datetime import datetime
,则需要找到并模拟所有这些(以及所有那些做from time import time
,等等)来保证当系统的各个部分问现在几点了?"完全一致(如果您使用 FPIM,您只需模拟两个相关模块).
我喜欢 FPIM,因为使用 multiply 限定名称而不是单限定名称确实没有太多附加值(而裸名和限定名称之间的区别巨大 -- 您可以所以通过限定名称获得更多的控制权,无论是单个名称还是多个名称,都比使用裸名可能获得的控制权多得多!).
嗯,不能把整个工作日都用来回答你的每一点——你的问题应该是六个问题;-).我希望这至少可以解决为什么 F 比 R 好"以及一些模拟/测试问题——归结为保留和增强精心设计的模块化(通过 F)而不是破坏它(通过 R).
Let from module import function
be called the FMIF coding style.
Let import module
be called the IM coding style.
Let from package import module
be called the FPIM coding style.
Why is IM+FPIM considered a better coding style than FMIF? (See this post for the inspiration for this question.)
Here are some criteria which lead me to prefer FMIF over IM:
- Shortness of code: It allows me to use shorter function names and thus help stick to the 80 columns-per-line convention.
- Readability:
chisquare(...)
appears more readable thanscipy.stats.stats.chisquare(...)
. Although this is a subjective criterion, I think most people would agree. - Ease of redirection: If I use FMIF and for some reason at some later time want to redirect python to define
function
fromalt_module
instead ofmodule
I need to change just one line:from alt_module import function
. If I were to use IM, I'd need to change many lines of code.
I am interested in all reasons why IM+FPIM may be better than FMIF, but in particular, I'd be interested in elaboration on the following points mentioned here:
Pros for IM:
- ease of mocking/injecting in tests. (I am not very familiar with mocking, though I recently learned what the term means. Can you show code which demonstrates how IM is better than FMIF here?)
- ability for a module to change flexibly by redefining some entries. (I must be misunderstanding something, because this seems to be an advantage of FMIF over IM. See my third reason in favor of FMIF above.)
- predictable and controllable behavior on serialization and recovery of your data. (I really don't understand how the choice of IM or FMIF affects this issue. Please elaborate.)
- I understand that FMIF "pollutes my namespace", but beyond being a negative-sounding phrase, I don't appreciate how this hurts the code in any concrete way.
Many thanks.
The negatives you list for IM/FPIM can often be ameliorated by appropriate use of an as
clause. from some.package import mymodulewithalongname as mymod
can usefully shorten your code and enhance its readability, and if you rename mymodulewithalongname
to somethingcompletelydifferent
tomorrow, the as
clause can be used as a single statement to edit.
Consider your pro-FMIF point 3 (call it R for redirection) vs your pro-FPIM point 2 (call it F for flexibility): R amounts to facilitating the loss of integrity of module boundaries, while F strenghtens it. Multiple functions, classes and variables in a module are often intended to work together: they should not be independently switched to different meanings. For example, consider module random
and its functions seed
and uniform
: if you were to switch the import of just one of them to a different module, then you'd break the normal connection between calls to seed
and results of calls to uniform
. When a module is well designed, with cohesion and integrity, R's facilitation of breaking down the module's boundaries is actually a negative -- it makes it easier to do something you're better off not doing.
Vice versa, F is what enables coordinated switching of coupled functions, classes, and variables (so, generally, of entities that belong together, by modularity). For example, to make testing repeatable (FPIM pro-point 1), you mock both seed
and random
in the random
module, and if your code follows FPIM, you're all set, coordination guaranteed; but if you have code that has imported the functions directly, you have to hunt down each such module and repeat the mocking over and over and over again. Making tests perfectly repeatable typically also requires "coordinated mocking" of date and time functions -- if you use from datetime import datetime
in some modules, you need to find and mock them all (as well as all those doing from time import time
, and so forth) to ensure that all the times received when the various parts of the system ask "so what time is it now?" are perfectly consistent (if you use FPIM, you just mock the two relevant modules).
I like FPIM, because there's really not much added value by using a multiply qualified name rather than a singly qualified one (while the difference between barenames and qualified names is huge -- you get so much more control with a qualified name, be it singly or multiply, than you possibly ever can with a barename!).
Ah well, can't devote all of the working day to responding to each and every one of your points -- your question should probably be half a dozen questions;-). I hope this at least addresses "why is F better than R" and some of the mocking/testing issues -- it boils down to preserving and enhancing well-designed modularity (via F) rather than undermining it (via R).
这篇关于“导入模块"是否比“从模块导入功能"更好的编码风格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!