Khi nào sử dụng os.name, sys.platform hoặc platform.system?


102

Theo những gì tôi biết, Python có 3 cách để tìm ra hệ điều hành đang chạy:

  1. os.name
  2. sys.platform
  3. platform.system()

Biết thông tin này thường hữu ích trong việc nhập có điều kiện hoặc sử dụng chức năng khác nhau giữa các nền tảng (ví dụ: time.clock()trên Windows và time.time()trên UNIX).

Câu hỏi của tôi là, tại sao có 3 cách khác nhau để làm điều này? Khi nào thì nên sử dụng một cách chứ không phải một cách khác? Cách nào là 'tốt nhất' (chắc chắn nhất trong tương lai hoặc ít có khả năng vô tình loại trừ một hệ thống cụ thể mà chương trình của bạn thực sự có thể chạy trên đó)?

Nó có vẻ như sys.platformcụ thể hơn os.name, cho phép bạn phân biệt win32từ cygwin(trái ngược với chỉ nt) và linux2từ darwin(trái ngược với chỉ posix). Nhưng nếu vậy, đó là sự khác biệt giữa sys.platformplatform.system()?

Ví dụ, cái nào tốt hơn, cái này:

import sys
if sys.platform == 'linux2':
    # Do Linux-specific stuff

hay cái này? :

import platform
if platform.system() == 'Linux':
    # Do Linux-specific stuff

Hiện tại, tôi sẽ tiếp tục sys.platform, vì vậy câu hỏi này không đặc biệt khẩn cấp, nhưng tôi sẽ rất biết ơn vì đã giải thích rõ về vấn đề này.


15
sử dụng sys.platform.startswith('linux')thay vì sys.platform == 'linux2'để tương thích trong tương lai
JFS

Câu trả lời:


67

Đi sâu một chút vào mã nguồn.

Đầu ra của sys.platformos.nameđược xác định tại thời điểm biên dịch. platform.system()xác định loại hệ thống tại thời điểm chạy.

  • sys.platform được chỉ định như một trình biên dịch xác định trong quá trình xây dựng cấu hình.
  • os.namekiểm tra xem module cụ thể nhất định os có sẵn (ví dụ posix, nt...)
  • platform.system()thực sự chạy unamevà có thể có một số chức năng khác để xác định loại hệ thống tại thời điểm chạy.

Đề xuất của tôi:

  • Sử dụng os.nameđể kiểm tra xem đó có phải là hệ thống tuân thủ posix hay không.
  • Sử dụng sys.platformđể kiểm tra xem đó có phải là linux, cygwin, darwin, Atheos, v.v.
  • Sử dụng platform.system()nếu bạn không tin các nguồn khác.

2
Tôi đã nghiên cứu thêm và đây là câu trả lời chi tiết: stackoverflow.com/a/58071295/207661 .
Shital Shah

20

Có một sự khác biệt nhỏ giữa platform.system()sys.platformvà thú vị là đối với hầu hết các trường hợp platform.system()suy thoái thànhsys.platform

Đây là những gì Nguồn Python2.7\Lib\Platform.py\systemnói

def system():

    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.

        An empty string is returned if the value cannot be determined.

    """
    return uname()[0]

def uname():
    # Get some infos from the builtin os.uname API...
    try:
        system,node,release,version,machine = os.uname()
    except AttributeError:
        no_os_uname = 1

    if no_os_uname or not filter(None, (system, node, release, version, machine)):
        # Hmm, no there is either no uname or uname has returned
        #'unknowns'... we'll have to poke around the system then.
        if no_os_uname:
            system = sys.platform
            release = ''
            version = ''
            node = _node()
            machine = ''

Cũng theo tài liệu

os.uname ()

Trả về 5 bộ chứa thông tin xác định hệ điều hành hiện tại. Tuple chứa 5 chuỗi: (sysname, nodename, release, version, machine). Một số hệ thống cắt bớt tên nút thành 8 ký tự hoặc thành phần đứng đầu; cách tốt hơn để lấy tên máy chủ là socket.gethostname () hoặc thậm chí socket.gethostbyaddr (socket.gethostname ()).

Availability: recent flavors of Unix.

11

Từ sys.platformtài liệu :

  • os.name có độ chi tiết thô hơn
  • os.uname() cung cấp thông tin phiên bản phụ thuộc vào hệ thống
  • Các platformmô-đun cung cấp kiểm tra chi tiết cho danh tính của hệ thống

Thường thì cách "tốt nhất" để kiểm tra xem một số chức năng có khả dụng hay không là thử sử dụng nó và sử dụng dự phòng nếu nó không thành công.

còn sự khác biệt giữa sys.platform và platform.system () thì sao?

platform.system()trả về giá trị bình thường mà nó có thể nhận được từ nhiều nguồn khác nhau: os.uname(), sys.platform, verlệnh (trên Windows).


10

Nó phụ thuộc vào việc bạn muốn nâng cao ngoại lệ hay thử bất cứ điều gì trên một hệ thống chưa được kiểm tra và liệu mã của bạn ở mức cao hay mức thấp đến mức nó có thể hoặc không thể hoạt động trên một hệ thống chưa được kiểm tra tương tự (ví dụ: Mac chưa được kiểm tra - 'posix' trở lên hệ thống nhúng ARM). Điều quan trọng hơn là không liệt kê tất cả các hệ thống đã biết mà để kiểm tra các đặc tính có thể có liên quan. (ví dụ: nó được coi là quan trọng về tính đặc biệt của hệ thống nhưng thuộc tính đa xử lý không quan trọng.)

  • os.name là độ phân giải đủ để sử dụng đúng osmô-đun. Các giá trị có thể có là 'posix', 'nt', 'os2', 'ce', 'java' hoặc 'riscos' trong Python 2.7, trong khi chỉ 'posix', 'nt' và 'java' được sử dụng kể từ Python 3.4.

  • sys.platform là một độ phân giải tốt hơn. Nên sử dụng if sys.platform.startswith('linux')thành ngữ vì "linux2" có nghĩa là phiên bản hạt nhân Linux 2.xx hoặc 3. Các hạt nhân cũ hơn hiện không bao giờ được sử dụng. Trong Python 3.3, tất cả các hệ thống Linux đều là 'linux' đơn giản.

Tôi không biết chi tiết cụ thể của hệ thống "Mac" và "Java" và vì vậy tôi không thể sử dụng kết quả của phương thức rất tốt platform.system () để phân nhánh, nhưng tôi sẽ sử dụng các ưu điểm của platformmô-đun cho các thông báo và ghi lỗi.


os.namegiá trị trả về có thể là 'posix', 'nt', 'java'theo Python 3 tài liệu . Xem thêm: tài liệu mô-đun nền tảng . Tôi không tin 'riscos''os2'là các giá trị có thể trả về từ os.name; chúng có thể là giá trị trả về từsys.platform . Các Python 3 sys.platformtài liệu không xuất hiện để được đầy đủ.
afeique,

1
@afeique: Tôi đã cập nhật câu trả lời của mình cho Python mới hơn, nhưng nó đã đúng vào thời điểm đó. Xem Python 3.3 - os.name (phiên bản mới nhất tại thời điểm đó). Python 2.7 vẫn được hỗ trợ và 'riscos' là một giá trị có thể có cho nó.
hynekcer

Cảm ơn @hynekcer, tôi đánh giá cao chỉnh sửa của bạn để thêm số phiên bản Python. Tôi xin lỗi vì không nhận ra nó đã thay đổi sau Python 3.3. Tôi đã không xem xét các phiên bản khác nhau của tài liệu và đưa ra giả định rằng hành vi của Python 3 os.namelà nhất quán giữa các phiên bản. Tôi cũng đã không kiểm tra lại tài liệu 2.7 , nhưng bây giờ tôi biết rằng bạn đã chính xác.
afeique

3

Tôi tin rằng mô-đun nền tảng có lẽ được ưu tiên cho mã mới. Những người khác đã tồn tại trước nó. Nó là một sự tiến hóa, và những cái khác vẫn để tương thích ngược.


7
Tôi tự hỏi liệu chúng tôi có thể nhờ bất kỳ nhà phát triển Python nào xác nhận điều này không. Thậm chí có thể là bất kỳ ai đã phát triển mô-đun nền tảng.
ztangent
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.