2012-03-22 36 views
7

Tôi có một tập lệnh tìm kiếm một thư mục chứa một tệp cụ thể, bắt đầu từ thư mục hiện tại và đi lên cây (nghĩ đến việc tìm ra thư mục .git nằm ở đâu).Kiểm tra xem thư mục có phải là một hệ thống tập tin (root system)

Phương pháp của tôi trông như thế này:

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 

Bây giờ vấn đề với phương pháp này là, nếu nó không thể tìm thấy thư mục, nó bẹ (và cuối cùng ngăn xếp tràn) vì rõ ràng khi tham gia /.. mang đến cho bạn / lần nữa. Tôi đã thử so sánh path với parent hoặc repr của chúng, nhưng điều đó không hoạt động (chúng luôn khác biệt). Cách giải quyết của tôi bây giờ là bao gồm một bộ đếm chiều sâu trong phương thức đệ quy và dừng lại ở một ngưỡng tối đa ngẫu nhiên nào đó.

Câu hỏi của tôi là như vậy, có cách đáng tin cậy trên nhiều nền tảng để kiểm tra xem tôi đã đạt đến thư mục gốc trong hệ thống tệp không?

+1

Tôi không hoàn toàn chắc chắn nếu nó là đáng tin cậy trên tất cả các nền tảng, nhưng nếu os.path.dirname (đường dẫn) == đường dẫn, sau đó nó có vẻ như đường dẫn là gốc. –

Trả lời

7

Tôi không nghĩ rằng bạn có thể tìm hiểu xem đó có phải là hệ thống tệp gốc một cách hợp lý hay không, tuy nhiên tôi khuyên bạn nên thực hiện cuộc gọi tới os.path.realpath() trên cả thư mục hiện tại và cha mẹ đã tính của bạn và so sánh nếu chúng giống nhau - điều này có nghĩa là bạn đang quay bánh xe của bạn và không có điểm trong tiến trình.

Ví dụ:

>>> os.path.realpath('/usr/bin/..') 
'/usr' 
>>> os.path.realpath('/usr/bin/../..') 
'/' 
>>> os.path.realpath('/usr/bin/../../..') 
'/' 
>>> os.path.realpath('/..') 
'/' 
16
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

Nó hoạt động trên các cửa sổ chia sẻ, nhưng nó không biểu thị chia sẻ là gốc ... nó nghĩ về \\ máy chủ là gốc. Điều đó thực sự làm cho IMO ý nghĩa hơn anyway. –

+0

@nacitarsevaht Bạn có lẽ đúng. Suy nghĩ của \\ server là root làm cho ý nghĩa hơn, nhưng làm cho sử dụng ít thực tế, như liệt kê nội dung của \\ máy chủ thông qua các công cụ bình thường mà làm "danh sách dir" là hầu như không thực tế. – ddotsenko

+0

Câu trả lời này không hoạt động nếu đường dẫn chứa các phần tử "..", chẳng hạn như trong câu trả lời của @ FatalError. – jmh

1

này làm việc cho chúng tôi trên Linux. Bạn không chắc chắn về Windows, tuy nhiên:

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) 

Chúng tôi sử dụng os.path.normpath (bắt đầu) trong cuộc gọi đến chức năng này.

Các vấn đề liên quan