如何获得路径的正确大小写?

1 python windows path python-3.x

假设我有一个代表目录的类(当然是简化的示例):

import os
class Dir:
    def __init__(self, path):
        self.path = os.path.normcase(path)
Run Code Online (Sandbox Code Playgroud)

为了使事情更容易在内部实现,我在将参数保存到属性之前调用os.path.normcasepath参数。这很好用,但它会小写路径:

>>> import os
>>> os.path.normcase(r'C:\Python34\Lib')
'c:\\python34\\lib'
>>>
Run Code Online (Sandbox Code Playgroud)

我想要一种方法将路径转回其正确的大写形式C:\Python34\Lib。我计划在方法内部执行此操作__repr__,以便获得不错的输出,例如:

>>> my_dir
Dir(r'C:\Python34\Lib')
>>>
Run Code Online (Sandbox Code Playgroud)

当我在交互式翻译中时。标准库中有类似的东西吗?


注意:我不是指用户作为参数提供的字符串path。如果用户这样做:

my_dir = Dir('c:\PYTHON34\lib')
Run Code Online (Sandbox Code Playgroud)

我仍然想Dir('C:\Python34\Lib')在解释器中打印,因为这是正确的大写。基本上,我希望输出的路径与文件资源管理器中的路径相同。

小智 5

更新:

对于那些使用较新版本的 Python 的用户来说,新pathlib模块具有以下形式的功能pathlib.Path.resolve

>>> from pathlib import Path
>>> Path(r'c:\python34\lib').resolve()
WindowsPath('C:/Python34/Lib')
>>> str(Path(r'c:\python34\lib').resolve())
'C:\\Python34\\Lib'
>>>
Run Code Online (Sandbox Code Playgroud)

因此,您可以将用户提供的路径存储为Path对象:

from pathlib import Path
class Dir:
    def __init__(self, path):
        self.path = Path(path)
Run Code Online (Sandbox Code Playgroud)

然后__repr__像这样实现方法:

def __repr__(self):
    return "Dir('{}')".format(self.path.resolve())
Run Code Online (Sandbox Code Playgroud)

作为额外的好处,我们不再需要该os.path.normcase函数,因为Path对象直接支持不区分大小写的比较。

但它的一个缺点pathlib是它仅在 Python 3.4(当前最新版本)中可用。因此,那些使用早期版本的用户将需要向后移植到其版本或使用os.path._getfinalpathname如下所示的功能。


当我深入研究标准库时,我在os.path名为 的模块中发现了一个未记录的函数_getfinalpathname

>>> import os
>>> os.path._getfinalpathname(r'c:\python34\lib')
'\\\\?\\C:\\Python34\\Lib'
>>>
Run Code Online (Sandbox Code Playgroud)

使用str.lstrip,我可以获得我需要的输出:

>>> os.path._getfinalpathname(r'c:\python34\lib').lstrip(r'\?')
'C:\\Python34\\Lib'
>>>
Run Code Online (Sandbox Code Playgroud)

这种方法的唯一缺点是该函数没有文档记录并且有些隐藏。但它目前适合我的需求(当然,如果您知道的话,我很想听到更好的方法:)