我一直想知道为什么从一个模块导入特定对象的语法是 from module import x, y, z
,而不是 import x, y, z from module
。我不是母语为英语的人,但后者难道不更正确/自然吗?
那么,将 from
放在前面的原因是什么呢?仅仅是为了简化语法(需要更少的先行符)吗?还是尝试使这两种导入方式在视觉上更加不同?或者这是其中一种情况,即显而易见的方式“除非你是荷兰人,否则一开始并不明显”? ;)
我不知道为什么要这样做,但这是我会采用的方式,因为作为一个工程师,从一般范畴开始并逐渐深入具体细节对我来说更加自然。
如果按顺序处理,这还意味着解析器需要存储较少的内容。例如:
import x, y, z from a
你需要记住 x
、y
和 z
。具体如下:
from a import x, y, z
你只需要记住a
。
这就是我第一次遇到Perl的后置if变体时为什么会有很多麻烦:
$x = $y if $y > 40;
由于您不知道所读内容是否有条件限制 事先。
from foo import ba<ctrl+space>
允许IDE实现自动完成(提供选项bar
、bat
、baz
...),因为它知道你要导入什么,然后再尝试自动完成。 - michael纯属猜测,可能完全没有意义,但我知道来自 Modula-2 的语法(天啊,那是二十年前的事了,我感觉自己老了)……也许 Python 受到了它的启发?
除了直接询问Guido,我认为你不会找到任何关于这个的解释。
这种语法从一开始就存在。我能找到的最早版本的Python源代码是Python 1.0.1。查看语法文件中的更改日志,我们可以找到更早版本的参考资料。在Python的第2版(我想我们正在讨论0.9.0之后的第二个发布版本)中,我们有以下注释:
# added 'from' NAME option on import clause, and '*' to import all;
这是与之同时添加的
# added class definition.
from x import y
而不是import y from x
。
import语句文档提供了实现import的基本算法:
在这两种版本的import语句中,该算法的第一步总是在最左边。我认为这对于一名语言实现者来说是最明显的排序方式,即使英语在反过来读可能更自然。导入语句分为两步执行:(1) 查找并初始化模块(如有必要); (2) 在局部名称空间中(该导入语句所在作用域)定义一个或多个名称。导入语句有两种形式,在是否使用from关键字上有所不同。第一种形式(不使用from)对列表中的每个标识符重复执行这些步骤。使用from的形式执行步骤(1) 一次,并重复执行步骤(2)。
我不知道这种语法的完整历史,因为它可以追溯到 Python 1.x 时代。但是我发现能够扫描源代码的左侧,并快速找到脚本依赖的模块名称非常有用。如果一个语句是 "import a,b,c,d,e,really_long_name, alsdf,lsdf from blah",那么我需要花一些时间才能找到该脚本依赖于 blah。
在英文中,可能更合理地说 from module import x, y, z
,但在编程中,先引入更通用的项目,然后再引入更具体的细节是更有意义的。
这可能不是唯一的原因,但对编译器或解释器来说会更容易处理。
尝试编写编译器,你就会明白我的意思 :D
SELECT Columns FROM Table
,它在自动完成方面也存在同样的问题。 - dan04这取决于你使用的编程语言语法。对我来说,使用这样的导入方式更容易阅读。
使用这种方式更容易阅读和理解吗?
From Grocery buy apple and orange
或者
Buy apple and orange from grocery.
Buy apple and orange from supermarket
第一个更适合我...
来自https://docs.python.org/3/reference/simple_stmts.html#import:
import foo # 导入foo并在本地绑定
import foo.bar.baz # 导入foo.bar.baz,foo在本地绑定
import foo.bar.baz as fbb # 导入foo.bar.baz并绑定为fbb
from foo.bar import baz # 导入foo.bar.baz并绑定为baz
from foo import attr # 导入foo并将foo.attr绑定为attr
我得出结论这是一个本地可用性/绑定的问题。
import(module, x, y, z)
。根本不需要使用from
。 - FMcimport
获得特殊的语法处理,那么您需要编写import('module', 'x', 'y', 'z')
,传递对象的 名称,因为在 导入 之后对象本身是不可用的。 - dan04import module (a, b, c)
。它干净、清晰,使多个导入语句看起来统一和对齐(除了import qualified
的情况,不幸的是)。而且我不知道为什么 GvR 选择了那个丑陋的from ... import
。 - firegurafiku