我有一个脚本,用于搜索包含特定文件的目录,从当前目录开始并上到树(考虑尝试找出.git
目录所在的位置)。
我的方法如下:
def getDir(self,cwd):
path = os.path.abspath(cwd)
if not os.path.isdir(path):
raise RuntimeError("getDir should not be run on files")
if FILE in os.listdir(path):
return path
parent = os.path.join(path, os.path.pardir)
if os.access(parent, os.R_OK) and os.access(parent, os.X_OK):
return self.getDir(parent)
else
return None
现在这个方法的问题是,如果它找不到目录,它会循环(并最终堆栈溢出),因为显然加入/
和..
会再次给你/
。我尝试将path
与parent
或repr
进行比较,但这不起作用(它们总是截然不同)。我现在的解决方法是在递归方法中包含深度计数器,并在某个随机最大阈值处停止。
我的问题是,是否有一种可靠的跨平台方式来检查我是否已到达文件系统中的根目录?
答案 0 :(得分:19)
if os.path.dirname(path) == path:
# you have yourself root.
# works on Windows and *nix paths.
# does NOT work on Windows shares (\\server\share)
答案 1 :(得分:8)
我不认为你可以看到它是否是一个文件系统根可移植,但我建议在当前目录和你计算的父目录上调用os.path.realpath()
并比较它们是否是同样 - 这意味着你正在转动你的车轮,没有必要继续前进。
例如:
>>> os.path.realpath('/usr/bin/..')
'/usr'
>>> os.path.realpath('/usr/bin/../..')
'/'
>>> os.path.realpath('/usr/bin/../../..')
'/'
>>> os.path.realpath('/..')
'/'
答案 2 :(得分:1)
这适用于Linux。但是不确定Windows:
def _find_root(start, stop, func=os.path.exists):
"""Search up the start hierarchy for stop; return None at the FS root.
Uses func() to determine if stop exists; default is os.path.exists().
"""
if func(os.path.join(start, stop)):
return start
else:
if os.path.samefile(start, os.path.dirname(start)):
return None
else:
return _find_root(os.path.dirname(start), stop)
我们在调用此函数时使用os.path.normpath(start)。