2012-09-26 33 views
12

Tôi đang học Python và tôi nhận thấy điều gì đó kỳ lạ với một trong các tập lệnh của tôi. Làm một thử nghiệm nhỏ, tôi đã khám phá ra vấn đề bắt nguồn từ hành vi này:Tại sao os.path.join vứt bỏ các đối số?

>>> import os 
>>> os.path.join('a','b') 
'a/b' 
>>> os.path.join('a','/b') 
'/b' 

Kiểm tra documentation, đây là, trên thực tế, việc thiết kế các chức năng:

os.path. tham gia (path1[, path2[ ... ]])

Tham gia một hoặc nhiều thành phần đường một cách thông minh. Nếu bất kỳ thành phần nào là đường dẫn tuyệt đối, tất cả các thành phần trước đó (trên Windows, bao gồm cả ký tự ổ đĩa trước đó, nếu có) sẽ bị vứt bỏ và tham gia tiếp tục. ...

Câu hỏi của tôi không phải là why my script failed mà là lý do tại sao hàm được thiết kế theo cách này. Tôi có nghĩa là, trên Unix ít nhất, a//b là một cách hoàn toàn chấp nhận được để chỉ định một con đường, nếu không thanh lịch. Tại sao chức năng được thiết kế theo cách này? Có cách nào để biết liệu một hoặc nhiều phần tử đường dẫn có bị hủy bỏ không trong quá trình kiểm tra từng chuỗi đường dẫn với os.path.isabs() không?


Ra khỏi tò mò, tôi cũng đã kiểm tra các trường hợp một thành phần đường dẫn kết thúc bằng một nhân vật os.sep:

>>> os.path.join('a/','b') 
'a/b' 

đó làm việc như mong đợi.

+0

Một cách dễ dàng, mặc dù không phù hợp để kiểm tra điều này là làm 'filename.lstrip ('/')' – voithos

+3

@voithos Làm cho nó 'filename.lstrip (os.sep)' và nó di động với hầu hết các nền tảng chính. – delnan

+0

@delnan: bạn phải thử nghiệm trên các cửa sổ, nơi nó là 'os.sep +'/''.. –

Trả lời

14

Một trường hợp hữu ích cho os.path.join('a', '/b') để trả lại /b sẽ là nếu bạn yêu cầu người dùng nhập tên tệp.

Người dùng có thể nhập hoặc là một đường dẫn tương đối đến thư mục hiện tại, hoặc một đường dẫn đầy đủ, và chương trình của bạn có thể xử lý cả hai trường hợp như thế này:

os.path.join(os.getcwd(), filename) 

In [54]: os.getcwd() 
Out[54]: '/tmp' 

In [55]: os.path.join(os.getcwd(), 'foo') 
Out[55]: '/tmp/foo' 

In [56]: os.path.join(os.getcwd(), '/foo/bar') 
Out[56]: '/foo/bar' 
+1

... hoặc bất kỳ thư mục nào khác thực sự, nếu có thư mục mặc định hợp lý cho ứng dụng. – delnan

+4

Và Guido đã ghi nhớ điều này từ chính [sửa đổi đầu tiên] (http://hg.python.org/cpython/file/5570dbb1ce55/Lib/posixpath.py#11) (trong đó hàm bắt đầu bằng 'cat', sau này để được đổi tên thành 'join'). –

+0

@Martijn Pieters: Điều đó rất thú vị. Tôi muốn tò mò nếu Guido từng giải thích mục đích đằng sau thiết kế. Và cảm ơn bạn unutbu cho chỉ ra một trường hợp sử dụng có ý nghĩa. –

1

nghĩ bạn đang viết một tiện ích như cd để kiểm tra thư mục mới, bạn sẽ sử dụng

os.path.join(currdir, newdir) 

Nếu chúng tôi er nhập /b bạn sẽ ngoại trừ nó để ném đối số đầu tiên. Điều này giữ cho nhiều điều bằng cách sử dụng thư mục hiện hành.

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