PEP 235 – 在不区分大小写的平台上导入
- 作者:
- Tim Peters <tim.peters at gmail.com>
- 状态:
- 最终版
- 类型:
- 标准跟踪
- 创建日期:
- 2001年2月21日
- Python 版本:
- 2.1
- 发布历史:
- 2001年2月16日
注意
这本质上是一个追溯性的PEP:该问题在2.1版本发布过程中出现得太晚,以至于无法在决定如何处理之前征求广泛意见,而且无法推迟到2.2,否则也会延迟Cygwin和MacOS X的移植。
动机
文件系统在不同平台之间有所不同,体现在它们是否保留文件名的大小写,以及平台C库文件打开函数是否坚持区分大小写的匹配。
case-preserving case-destroying
+-------------------+------------------+
case-sensitive | most Unix flavors | brrrrrrrrrr |
+-------------------+------------------+
case-insensitive | Windows | some unfortunate |
| MacOSX HFS+ | network schemes |
| Cygwin | |
| | OpenVMS |
+-------------------+------------------+
在左上角框中,如果创建“fiLe”,它将存储为“fiLe”,并且只有open("fiLe")才能打开它(open("file")不能,其他14种变体也不能)。
在右下角框中,如果创建“fiLe”,无法确定它存储为什么——但最可能是“FILE”——并且open("FilE")的16种明显变体中的任何一种都可以打开它。
左下角框是一个混合:创建“fiLe”会在平台目录中存储“fiLe”,但打开它时不必匹配大小写;open("FILe")的16种明显变体中的任何一种都有效。
这些都不会改变!Python将继续遵循平台约定,即在创建文件时是否保留大小写,以及open()是否要求区分大小写的匹配。实际上,您应该始终像匹配区分大小写一样编写代码,否则您的程序将不具有可移植性。
提议更改的是Python“import”语句的语义,并且只在左下角进行更改。
当前左下角语义
对MacOSX HFS+和Cygwin的支持在2.1中是新增的,因此那里没有发生任何变化。正在改变的是Windows的行为。以下是Windows上当前导入规则
- 尽管文件系统不区分大小写,Python仍坚持区分大小写的匹配。但它不像左上角框那样工作:如果您在
sys.path上有两个文件,FiLe.py和file.py,并且执行import file
那么如果Python首先找到
FiLe.py,它会引发NameError。它不会继续寻找file.py;实际上,除了sys.path上第一个不区分大小写的匹配之外,不可能导入任何其他文件,而且只有当第一个不区分大小写的匹配完全匹配大小写时才可以导入。 - 一个糟糕的例外:如果在
sys.path上第一个不区分大小写的匹配的文件名是全大写(FILE.PY或FILE.PYC或FILE.PYO),那么无论导入语句中使用何种大小写混合,导入都会悄悄地抓取它。这显然是为了迎合真正符合右下角框的糟糕的旧文件系统。但这个例外是Windows独有的,原因可能存在也可能不存在。 - 另一个例外:如果环境变量
PYTHONCASEOK存在,Python会悄悄地抓取任何类型的第一种不区分大小写的匹配。
所以这些Windows规则非常复杂,既不符合Unix规则,也不提供文件系统固有的自然语义。这使得它们难以向Unix或Windows用户解释。然而,它们多年来一直运行良好,并且在独立的情况下没有 compelling 的理由去改变它们。
然而,那是在MacOSX HFS+和Cygwin移植出现之前。它们也具有大小写保留但大小写不敏感的文件系统,但进行移植的人鄙视Windows规则。实际上,一个让HFS+在导入时像Unix一样工作的补丁通过了评审并进入了代码库,这无意中也使Cygwin像Unix一样工作(但这得到了Cygwin人员的无限批准,所以他们肯定没有抱怨——他们有自己的补丁等待完成这项工作,但这些补丁的评审员却拒绝了)。
在更高层面上,我们希望通过在所有具有大小写保留但大小写不敏感文件系统的平台上遵循相同的规则来保持Python的一致性。
提议的语义
左下角框的建议新语义
- 如果
PYTHONCASEOK环境变量存在,与以前相同:静默接受任何类型的第一种不区分大小写的匹配;如果未找到,则引发ImportError。 - 否则,搜索
sys.path以查找第一个区分大小写的匹配;如果未找到,则引发ImportError。
#B与Unix上使用的规则相同,因此这将提高跨平台可移植性。这很好。#B也是Mac和Cygwin用户想要的规则(并且他们非常渴望自己多次实现,这在PythonLand是一个有力的论据)。它不会导致任何现有的非异常Windows导入失败,因为任何现有的非异常Windows导入首先会在路径中找到区分大小写的匹配——并且它仍然会。当前的异常Windows导入会以NameError或ImportError的形式失败,在后一种情况下它仍然会失败,在前一种情况下它会继续搜索,然后成功或以ImportError的形式失败。
#A是为了迎合挂载在Windows上的大小写不敏感文件系统,并且可能也会被那些热爱“自然”Windows行为并愿意设置环境变量以获得这种行为的人使用。我无意在Unix上也实现#A,但这仅仅是因为我不清楚我如何才能高效地做到这一点(我不会仅仅为了理论上的纯粹性而降低Unix下的导入速度)。
潜在的损害在这里:提议取消#2(匹配ALLCAPS.PY)。大小写不敏感文件系统正在逐渐消失,对它们的支持也很糟糕。我们已经(并将继续)支持PYTHONCASEOK以造福它们,但它们在2001年不值得多个黑客手段。
来源:https://github.com/python/peps/blob/main/peps/pep-0235.rst