2012-05-07 25 views
18

tôi chắc chắn rằng đó là cố ý, vì vậy ai đó có thể giải thích lý do cho hành vi này:Tại sao tôi buộc phải os.path.expanduser trong python?

Python 2.7.2 (default, Oct 13 2011, 15:27:47) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from os.path import isdir,expanduser 
>>> isdir("~amosa/pdb") 
False 
>>> isdir(expanduser("~amosa/pdb")) 
True 
>>> 
>>> from os import chdir 
>>> chdir("~amosa/pdb") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OSError: [Errno 2] No such file or directory: '~amosa/pdb' 
>>> chdir(expanduser("~amosa/pdb")) 
>>> 

Nó thực sự gây phiền nhiễu từ đó, sau khi tất cả, con đường với một tên người dùng trong đó thể được giải quyết một cách rõ ràng ... Tôi muốn viết mã có thể xử lý bất kỳ loại đầu vào nào mà người dùng có thể cho tôi, nhưng hành vi này yêu cầu tôi gọi expanduser trên mọi đường dẫn mà mã của tôi phải xử lý. Nó cũng có nghĩa là bất cứ nơi nào tôi in đường dẫn đó ra cho người dùng xem, nó sẽ hơi dễ đọc hơn so với những gì họ đã cho tôi.

Điều này có vẻ không phù hợp với các khái niệm về "gõ vịt", trong đó tôi khái quát để có nghĩa là tôi mong đợi python không rên rỉ với tôi, trừ khi có thực sự là một vấn đề ...

+5

Tôi không biết. Là một nhà phát triển Python, tôi đánh giá cao thực tế là Python không đi xung quanh các chuỗi mở rộng một cách kỳ diệu vào tôi trừ khi tôi yêu cầu một cách rõ ràng hành vi đó. Nếu bạn thực hiện mã của bạn đúng cách, bạn có thể tập trung các cuộc gọi của bạn vào 'expanduser' để làm cho nó ít phiền toái hơn. – larsks

+4

'chdir' giả định đó là tên chữ. Và đó chắc chắn không phải là cách gõ vịt nghĩa là gì. –

+0

Tạo một hàm xử lý tất cả các hành vi. Python cung cấp cho bạn chức năng cốt lõi. – Blender

Trả lời

20

Bởi vì các cuộc gọi hệ thống cơ bản không nhận ra đường dẫn người dùng và API truy cập tệp là một trình bao bọc khá mỏng trên chúng.

Thêm vào đó, nó sẽ là khá đáng ngạc nhiên cho người dùng không Unix,
if (ví dụ) fopen("~foo") trả về một "foo: không có người dùng như" lỗi (như "~foo" là một tên hồ sơ hợp lệ, ví dụ, windows) ...
Hoặc tương tự, nếu fopen("~administrator") lợi nhuận một lỗi như "có phải là một thư mục: C: \ Documents and Settings \ Administrator \".

Cuối cùng, như người nhận xét đã lưu ý: bạn đang nhầm lẫn "gõ vịt" với "phím tắt hữu ích", hai điều hoàn toàn khác nhau:
- Nhập liệu vịt cho phép tôi thay thế bất cứ thứ gì vịt giống như vịt .
- Phím tắt hữu ích cho phép tôi thay thế cho vịt bất kỳ thứ gì mà có thể được tạo thành quack giống như một con vịt (Python không "cố gắng làm cho nó quack" giống như một số ngôn ngữ khác).

+1

'~ foo' cũng là tên hợp lệ trên linux và hầu hết các cài đặt posixy khác. – SingleNegationElimination

+0

Tôi đoán việc gõ vịt trong tâm trí của tôi là "cố gắng làm cho nó quack" trước khi phàn nàn. Trong trường hợp này, Python không cố gắng hết sức. Tôi thực sự thích python vì thật dễ dàng để viết mã mà chỉ hoạt động. Nhưng khi nói đến việc python để làm shell scripting, tôi thấy tôi đang viết rất nhiều mã tiện ích của riêng mình. – amos

+1

Ah, vâng - đó là sự khác biệt.Python không "cố gắng để làm cho nó quack" giống như một số ngôn ngữ khác làm (ví dụ, Python ném lỗi cho: '1 +" 2 "', 'object(). Foo', và tham chiếu một biến không xác định). –

5

Trong tiện ích Unix bình thường, cú pháp ~amosa được xử lý bởi vỏ, đó là chương trình dùng để gọi các tiện ích. Bản thân các tiện ích không biết về cú pháp đặc biệt ~ (thường).

Vì vậy, nếu chương trình python của bạn được gọi bởi một lớp vỏ trên Unix, nó sẽ chỉ làm việc:

$ python -c 'import sys; print sys.argv[1]' ~drj 
/home/drj 

Chú ý cách chương trình python trên in con đường mở rộng, mặc dù nó rõ ràng không có mã để làm tự mở rộng. Vỏ mở rộng nó.

+1

Đây là một điểm hữu ích, vì trong chương trình chấp nhận đầu vào từ dòng lệnh, nó có thể xuất hiện cho người mới bắt đầu mà python không mở rộng, mặc dù điều này thực sự đang được thực hiện bởi trình bao. Điều này có thể dẫn đến sự nhầm lẫn khi thêm tên tệp theo chương trình hoặc từ đầu vào của người dùng, nơi việc mở rộng này không xảy ra. – zstewart

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