用反斜杠继续写一长行:
from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
LEFT, DISABLED, NORMAL, RIDGE, END
编写多个导入语句:
from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END`
(import *是不是一种选择;-)
相反,应该可以使用Python的标准分组机制(括号)编写import语句:
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
LEFT, DISABLED, NORMAL, RIDGE, END)
提案的这一部分从一开始就获得了BDFL的批准。括号支持已添加到Python 2.4。
绝对import的理由:
在Python 2.4和更早版本中,如果您正在读取位于包内的模块,则不清楚是否
import foo
是指顶层模块或包装内的另一个模块。随着Python库的扩展,越来越多的现有软件包内部模块突然无意间掩盖了标准库模块。包内部的问题特别棘手,因为无法指定要使用的模块。为了解决歧义,建议foo始终是sys.path可以访问的模块或包 。这称为绝对导入。
python-dev社区选择了绝对导入作为默认导入,因为它们是更常见的用例,并且因为绝对导入可以提供相对(包内)导入的所有功能-尽管以较高的价格重命名包中的内容会付出一定的代价在层次结构中向上移动或将一个程序包移入另一个程序包中。
由于这表示语义上的变化,因此在Python 2.5和2.6中,绝对导入将是可选的,方法是使用
from __future__ import absolute_import
提案的这一部分从一开始就获得了BDFL的批准。
相对import的理由
随着向绝对import的转变,出现了一个问题,即是否应该允许相对import。提出了几个用例,其中最重要的是能够重新排列大型程序包的结构而无需编辑子程序包。另外,如果没有相对的导入,包中的模块就无法轻易地导入自身。
Guido批准了相对导入的想法,但是在拼写(语法)上存在很多分歧。似乎确实达成共识,相对导入将要求列出要导入的特定名称(即,将foo作为裸词始终将是绝对导入)。
以下是竞争者:来自Guido的一位:
from .foo import bar
或者
from ...foo import bar
这两种形式具有两种不同的建议语义。一种语义是使每个点代表一个级别。关于计数点的困难有许多抱怨。另一种选择是只允许一个级别的相对导入。那会丢失很多功能,人们仍然抱怨缺少单点形式的点。最后的选择是定义一种算法,用于查找相关的模块和软件包。这里的反对意见是“明确胜于隐含”。(建议的算法是“从当前程序包目录中搜索,直到最终的父程序包被命中为止。”)
有人建议使用其他标点符号作为分隔符,例如“-”或“ ^”。
有人建议使用“ *”:
from *.foo import bar
下一组选项是从多个海报中混合而成的:
from __pkg__.__pkg__ import
和
from .__parent__.__parent__ import
许多人(包括圭多)认为,这些看起来很丑陋,但他们是 清晰和明确。总体而言,更多的人更喜欢__pkg__作为较短的选择。
一种建议是仅允许同级引用。换句话说,您将无法使用相对导入来引用包树中更高级别的模块。然后,您将可以执行以下任一操作
from .spam import eggs
或
import .spam.eggs
有些人赞成允许索引的父母:
from -2.spam import eggs
在这种情况下,从当前目录导入将很简单
from .spam import eggs
最后,当您想在包中进行挖掘时,某些人不喜欢将导入更改 为从…导入的方式。他们建议完全重写导入语法:
from MODULE import NAMES as RENAME searching HOW
或
import NAMES as RENAME from MODULE searching HOW
[from NAMES] [in WHERE] import
但是,这很可能无法在Python 2.5中实现(变化太大),并且允许相对导入非常关键,以至于我们现在需要一些东西(假设标准 导入将变为绝对导入)。不仅如此,此提议的语法还存在几个未解决的问题:
精确建议的语法是什么?(在哪种情况下,哪些子句是可选的?)
search子句的绑定强度是多少?换句话说,您是否写:
import foo as bar searching XXX, spam as ham searching XXX
或
import foo as bar, spam as ham searching XXX
圭多的决定
Guido宣布[1],相对import将使用前导点。单个前导点表示从当前包开始的相对导入。两个或多个前导点将相对导入当前程序包的父级,第一个点后每个点一个级别。这是一个示例包布局:
package/
__init__.py
subpackage1/
__init__.py
moduleX.py
moduleY.py
subpackage2/
__init__.py
moduleZ.py
moduleA.py
假设当前文件是moduleX.py或 subpackage1 / __ init__.py,则以下是新语法的正确用法:
from .moduleY import spam
from .moduleY import spam as ham
from . import moduleY
from ..subpackage1 import moduleY
from ..subpackage2.moduleZ import eggs
from ..moduleA import foo
from ...package import bar
from ...sys import path
请注意,尽管最后一种情况是合法的,但绝对不建议使用(Guido使用了“疯狂”一词)。
相对导入必须始终使用from <> import ; import <>始终是绝对的。当然,绝对导入可以 通过省略前导点从<>导入中使用。禁止导入.foo的原因是因为之后
import XXX.YYY.ZZZ
then
XXX.YYY.ZZZ
在表达式中可用。但
.moduleY
在表达式中不可用。
相对import和__name__
相对导入使用模块的__name__属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,将其设置为’main’),则相对导入的解析就好像该模块是顶级模块一样,无论该模块实际位于文件系统上的何处。
sys.modules中的相对导入和间接入口
当引入软件包时,sys.modules中的间接条目的概念应运而生[2]。当sys.modules中某个包中某个模块的条目的值为None时,表示该模块实际上引用了顶层模块。例如,“ Sound.Effects.string”在sys.modules中的值为None。这意味着任何解析为该名称的导入实际上就是导入顶级“字符串”模块。
这为何时相对导入要解析为绝对导入引入了优化。但是,由于此PEP在绝对导入和相对导入之间做出了非常清晰的划分,因此不再需要这种优化。当绝对/相对导入成为唯一可用的导入语义时,将不再支持sys.modules中的间接条目。