2010-04-27 40 views
103

Theo số official documentation, os.path là một mô-đun. Vì vậy, cách ưa thích của việc nhập khẩu nó là gì?Tôi có nên sử dụng `import os.path` hoặc` import os`?

# Should I always import it explicitly? 
import os.path 

Hoặc ...

# Is importing os enough? 
import os 

Vui lòng KHÔNG trả lời "nhập khẩu os công trình đối với tôi". Tôi biết, nó làm việc cho tôi quá ngay bây giờ (như của Python 2.6). Điều tôi muốn biết là bất kỳ đề xuất chính thức nào về vấn đề này. Vì vậy, nếu bạn trả lời câu hỏi này, vui lòng đăng tham chiếu của bạn.

Trả lời

121

os.path hoạt động theo cách hài hước.Có vẻ như os phải là một gói có một mô-đun con số path, nhưng trong thực tế os là một mô-đun bình thường làm phép thuật với sys.modules để tiêm os.path. Đây là những gì sẽ xảy ra:

  • Khi Python khởi động, nó tải một loạt mô-đun vào sys.modules. Chúng không bị ràng buộc với bất kỳ tên nào trong tập lệnh của bạn, nhưng bạn có thể truy cập các mô-đun đã được tạo khi bạn nhập chúng theo một cách nào đó.

    • sys.modules là dict trong đó mô-đun được lưu trong bộ nhớ cache. Khi bạn nhập một mô-đun, nếu nó đã được nhập vào một nơi nào đó, nó sẽ nhận được cá thể được lưu trữ trong sys.modules.
  • os là một trong các mô-đun được tải khi Python khởi động. Nó gán thuộc tính path của nó cho một mô-đun đường dẫn đặc trưng cho os.

  • Nó tiêm sys.modules['os.path'] = path để bạn có thể thực hiện "import os.path" như thể nó là một mô-đun con.

tôi có xu hướng nghĩ về os.path như một module Tôi muốn sử dụng hơn một điều trong os mô-đun, vì vậy mặc dù nó không phải thực sự một submodule của một gói gọi os, tôi nhập nó giống như là một và Tôi luôn làm import os.path. Điều này phù hợp với cách os.path được ghi lại.


Vô tình, loại cấu trúc này dẫn đến sự nhầm lẫn sớm của lập trình viên Python về các mô-đun và gói và tổ chức mã, tôi nghĩ vậy. Đây thực sự là vì hai lý do

  1. Nếu bạn nghĩ về os như là một gói và biết rằng bạn có thể làm import os và được tiếp cận với các submodule os.path, bạn có thể ngạc nhiên sau khi bạn không thể làm import twisted và tự động truy cập twisted.spread mà không cần nhập.

  2. Thật khó hiểu rằng os.name là điều bình thường, một chuỗi và os.path là một mô-đun. Tôi luôn luôn cấu trúc các gói của mình với các tệp rỗng __init__.py để cùng cấp tôi luôn có một loại điều: một mô-đun/gói hoặc các nội dung khác. Một số dự án Python lớn sử dụng phương pháp này, có xu hướng tạo ra mã có cấu trúc hơn.

+0

Câu trả lời xuất sắc, rất có nhiều thông tin! Xin chúc mừng! Mặc dù nó không trả lời trực tiếp câu hỏi, nhưng nó có rất nhiều chi tiết hữu ích. Nhưng bạn có thể vui lòng xây dựng trên "Điều này phù hợp với cách os.path được ghi lại" không? Giống như Chris Hulan đã nói, ví dụ os.walk() chỉ nhập os thay vì os.path. –

+3

@Denilson, Nó bao gồm một câu trả lời trực tiếp: Tôi luôn luôn làm 'nhập os.path' bản thân mình và nghĩ rằng đó là một cách đẹp hơn. Bởi "Điều này phù hợp với cách os.path được ghi lại" Tôi có nghĩa là nó được đưa ra trang riêng của nó trong tài liệu tại http://docs.python.org/library/os.path.html. –

+0

Tại sao? Tại sao nó được thực hiện theo cách này? – user1712447

6

Điều thú vị là đủ, nhập os.path sẽ nhập tất cả các os. hãy thử những điều sau trong lời nhắc tương tác:

import os.path 
dir(os) 

Kết quả sẽ giống như khi bạn vừa nhập os. Điều này là do os.path sẽ tham chiếu đến một mô-đun khác dựa trên hệ điều hành nào bạn có, vì vậy python sẽ nhập os để xác định mô-đun nào cần tải cho đường dẫn.

reference

Với một số mô-đun, nói import foo sẽ không vạch trần foo.bar, vì vậy tôi đoán nó thực sự phụ thuộc thiết kế của các module cụ thể.


Nói chung, chỉ cần nhập mô-đun rõ ràng bạn cần phải nhanh hơn một chút. Trên máy tính của tôi:

import os.path:7.54285810068e-06 giây

import os:9.21904878972e-06 giây

Những thời gian được tính đủ gần để được khá đáng kể. Chương trình của bạn có thể cần phải sử dụng các mô-đun khác từ os hoặc ngay bây giờ hoặc sau đó, vì vậy thường có nghĩa là chỉ cần hy sinh hai micro giây và sử dụng import os để tránh lỗi này sau. Tôi thường phụ thuộc vào việc chỉ cần nhập toàn bộ hệ điều hành, nhưng có thể thấy lý do tại sao một số người thích import os.path về mặt kỹ thuật hiệu quả hơn và truyền đạt tới người đọc mã đó là phần duy nhất của mô-đun os cần được sử dụng. Về cơ bản nó tóm lại câu hỏi về phong cách trong đầu tôi.

+2

'từ path' os nhập khẩu sẽ làm cho các cuộc gọi đến con đường nhanh hơn nếu tốc độ là vấn đề. –

+0

Là pythonic, rõ ràng là tốt hơn là ngầm phải không? Trong thực tế, tôi nghĩ đó thực sự là lời gọi phán đoán của người dùng, cho dù người dùng chỉ sử dụng os.path hoặc nhiều mô-đun trong os. Có thể một phương pháp phù hợp hơn với triết lý của bạn so với phương pháp khác? –

+14

Thời gian này là một số tối ưu hóa sớm sớm nhất mà tôi từng thấy. Điều này chưa bao giờ là nút cổ chai * của bất kỳ ai và thời gian ở đây là không quan trọng đối với cách ai đó nên mã hóa. –

4

Không thể tìm thấy bất kỳ tài liệu tham khảo dứt khoát, nhưng tôi thấy rằng mã ví dụ cho os.walk sử dụng os.path nhưng chỉ nhập khẩu os

27

Theo PEP-20 bởi Tim Peters, "Rõ ràng là tốt hơn tiềm ẩn" và "Khả năng đọc đếm ". Nếu tất cả những gì bạn cần từ mô-đun os dưới os.path, import os.path sẽ rõ ràng hơn và cho người khác biết những gì bạn thực sự quan tâm. Tương tự như vậy, PEP-20 cũng nói "Đơn giản là tốt hơn phức tạp", vì vậy nếu bạn cũng cần những thứ nằm trong ô os tổng quát hơn, thì import os sẽ được ưu tiên hơn.

+2

Tôi không thấy làm thế nào 'nhập os' thực sự là về" đơn giản "trong bất kỳ cách có ý nghĩa. Đơn giản! = Ngắn. –

+10

Tôi đã cố gắng để chỉ ra rằng 'nhập os' ** và ** một' os.path nhập 'là daft nếu bạn ví dụ cần 'os.getcwd()' và 'os.path.isfile()' –

14

Câu trả lời cuối cùng: import os và sử dụng os.path. không trực tiếp import os.path.

Từ các tài liệu của các mô-đun riêng của mình:

>>> import os 
>>> help(os.path) 
... 
Instead of importing this module directly, import os and refer to 
this module as os.path. The "os.path" name is an alias for this 
module on Posix systems; on other systems (e.g. Mac, Windows), 
os.path provides the same operations in a manner specific to that 
platform, and is an alias to another module (e.g. macpath, ntpath). 
... 
+7

Lưu ý rằng đó không phải là tài liệu cho mô-đun 'os.path' không tồn tại, nhưng đối với' posixpath'. – wRAR

+8

Đó không phải là tất cả cách tôi nghĩ rằng docstring có nghĩa là để được giải thích, mặc dù nó là khá gây hiểu lầm. Hãy nhớ rằng câu "" Thay vì nhập trực tiếp mô-đun này, hãy nhập os và tham khảo mô-đun này là os.path. "' Nằm trong 'posixpath.py' (hoặc' macpath.py', 'ntpath.py 'vv). Tôi khá chắc chắn rằng những gì họ có nghĩa là không nên 'nhập posixpath' (hoạt động), mà là nhập mô-đun thông qua 'os' để có tính di động tốt hơn. Tôi không nghĩ rằng họ có ý định đưa ra một khuyến nghị về việc liệu 'os os' hay 'import os.path' có được ưu tiên hay không. – flornquake

+1

Tôi đồng ý với hầu hết nhận xét của @flornquake nhưng không đồng ý với câu cuối cùng. Cả posixpath.py và ntpath.py đều nói "os nhập và tham chiếu đến mô-đun này là os.path". Họ không nói "os.path nhập khẩu và tham khảo mô-đun này như os.path". macpath.py không có gì về vấn đề này. –

0

Tôi đồng ý với Mike

Tôi nghĩ

import os là tốt.

Bạn chỉ sau đó có đề cập đến chi tiết như thế này

os.path() 

hoặc nếu bạn đang gọi một module trong một module

os.path.exists()