【问题标题】:How to write Python doctest that is OS independent regarding path separator如何编写独立于操作系统的关于路径分隔符的 Python doctest
【发布时间】:2014-08-12 07:27:16
【问题描述】:

有没有办法以文件路径作为输出的 doctest,无论它在哪个操作系统上运行,它都会成功?

例如,在 Windows 上这将起作用:

r"""
>>> import foo
>>> relative_path = foo.getRelativePath()
>>> print relative_path 
'bar\\foobar'
"""
if __name__ == '__main__':
    from doctest import testmod
    print testmod()

但当然会在 Linux 上失败并产生类似于以下内容的错误:

Failed example:
    print relative_path 
Expected:
    'bar\\foobar'
Got:
    'bar/foobar'

我怎样才能在任何操作系统上进行上述工作?

编辑

我知道我可以这样做:

>>> relative_path == os.path.join('bar', 'foobar')
True

但我想知道是否有其他更好的方法来做到这一点。

【问题讨论】:

    标签: python-2.6 doctest


    【解决方案1】:

    澄清

    Doctests 因其简单性而具有吸引力,但这是一种误导性的简单性。您希望测试行代表一个表达式, doctest 将根据最后一个表达式的结果进行评估,但事实并非如此;它实际上只是做一个简单的基本字符串比较。

    #doctesttest.py
    """
    >>> "test"
    "test"
    
    python -m doctest doctesttest.py
    

    给予

    ...
    Expected:
        "test"
    Got:
        'test'
    

    虽然 - 在 python 术语中 - "test" == 'test',甚至 "test" is 'test'str(""" 'test' """) 不匹配 str(""" "test" """)

    以这种意识武装...

    解决方案

    以下将在所有系统上失败:

    def unique_paths(path_list):
        """ Returns a list of normalized-unique paths based on path_list
        >>> unique_paths(["first/path", ".\\first/path", "second/path"])
        ['first/path', 'second/path']
        """
    
        return set(os.path.normpath(p) for p in path_list)
    
    1. 我们得到的是一组,而不是一个列表,
    2. 将集合转换为列表需要提供一致的顺序,
    3. doctest 使用 eval 所以“.\first”中的“\”会被转换成“\”。

    我们正在寻找一个简单的字符串匹配,所以我们需要寻找一个容易匹配的结果string。你不关心分隔符,所以要么消除它,要么替换它,或者围绕它进行测试:

    def unique_paths(path_list):
        """ Returns a list of normalized-unique paths based on path_list
        >>> paths = unique_paths(["first/path", ".\\\\first/path", "second/path"])
        >>> len(paths)
        2
        >>> [os.path.split(path) for path in sorted(list(paths))]
        [('first', 'path'), ('second', 'path')]
        # or heck, even
        >>> sorted(list(paths[0])).replace('\\\\', '/')
        'first/path'
        """
        return set(os.path.normpath(p) for p in path_list)
    

    【讨论】:

      【解决方案2】:

      可以通过调用获取依赖于os的路径分隔符

      sep = os.sep
      

      然后处理您正在使用的平台的相对路径。或者你可以使用

      os.abspath()
      

      相反。有多种选择(请参阅http://pymotw.com/2/ospath/)。我采用了 abspath-variant。

      -金

      【讨论】:

      • 我的问题是关于 doctest 输出中的路径分隔符,而不是一般的 Python。
      • 哦,对不起。我误解了这个问题。
      【解决方案3】:

      只需放弃路径名操作函数(os.path.joinos.path.split 等)。你能说出/ 不起作用的情况吗?根据我的经验,这些很少而且相差甚远,而且都是在 cmd.execommand.com 中调用 Windows 原生程序的上下文中(这些程序通常使用 @ 987654324@ 选项)。在这个特定场景之外,正斜杠在 Windows 中的大多数情况下都有效,我敢打赌你不是针对 VAX/VMS。

      【讨论】:

      • OP 在询问测试,您的回答表明在 2014 年您可能需要了解更多有关测试的知识。可以从各种地方引入非/分隔符:a) 文件内容,b) 用户输入,c) system() 调用和管道读取,d) sys.path,e) os.walk,f) fuse 文件系统, ...
      猜你喜欢
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 2011-01-09
      • 2010-09-12
      • 2013-06-14
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多