web-dev-qa-db-ja.com

os.name、sys.platform、またはplatform.systemを使用する場合

私の知る限り、Pythonには、どのオペレーティングシステムが実行されているかを調べる3つの方法があります。

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

この情報を知ることは、条件付きインポートや、プラットフォーム間で異なる機能を使用する場合に役立ちます(たとえば、Windowsの場合はtime.clock()、UNIXの場合はtime.time())。

私の質問は、なぜこれを行う3つの異なる方法ですか?ある方法を使用し、別の方法を使用しない場合どの方法が「最良」であるか(最も将来性がある、またはプログラムが実際に実行できる特定のシステムを誤って除外する可能性が最も低い)?

sys.platformos.nameよりも具体的で、win32cygwinと区別し(ntとは対照的に)、linux2darwinとを区別することができます(posixとは対照的)。しかし、そうであれば、sys.platformplatform.system()の違いはどうですか?

たとえば、これは優れています、これ:

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

それともこれ? :

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

今のところ、sys.platformにこだわるので、この質問は特に緊急ではありませんが、これに関するいくつかの明確化に非常に感謝します。

90
ztangent

ソースコードを少し掘り下げました。

_sys.platform_および_os.name_の出力は、コンパイル時に決定されます。 platform.system()は、実行時にシステムタイプを決定します。

  • _sys.platform_は、ビルド構成時にコンパイラー定義として指定されます。
  • _os.name_は、特定のOS固有のモジュールが使用可能かどうかを確認します(例:posixnt、...)
  • platform.system()は実際にunameおよび潜在的に他のいくつかの関数を実行して、実行時にシステムタイプを決定します。

私のおすすめ:

  • _os.name_を使用して、posix準拠のシステムかどうかを確認します。
  • _sys.platform_を使用して、Linux、cygwin、darwin、atheosなどであるかどうかを確認します。
  • 他のソースを信じない場合は、platform.system()を使用してください。
59
moooeeeep

platform.system()と_sys.platform_には細かな違いがあり、興味深いことにほとんどの場合platform.system()は_sys.platform_に縮退します

ソース_Python2.7\Lib\Platform.py\system_が言うこと

_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 = ''
_

また、 ドキュメント

os.uname()

現在のオペレーティングシステムを識別する情報を含む5タプルを返します。 Tupleには、5つの文字列(sysname、nodename、release、version、machine)が含まれています。一部のシステムは、ノード名を8文字または先頭のコンポーネントに切り捨てます。ホスト名を取得するより良い方法は、socket.gethostname()またはsocket.gethostbyaddr(socket.gethostname())です。

_Availability: recent flavors of Unix.
_
19
Abhijit

_sys.platform_ docs から:

  • _os.name_ の粒度が粗い
  • os.uname() はシステム依存のバージョン情報を提供します
  • platform モジュールは、システムのIDの詳細なチェックを提供します

多くの場合、一部の機能が利用可能かどうかをテストするための「最良の」将来性のある方法は、機能を使用して、失敗した場合にフォールバックを使用することです。

sys.platformとplatform.system()の違いはどうですか?

platform.system() は、いくつかのソースから取得する正規化された値を返します:os.uname()、_sys.platform_、verコマンド(Windowsの場合)。

10
jfs

テストされていないシステムで例外を発生させるか、何かを試すか、コードが非常に高レベルまたは低レベルであり、同様のテストされていないシステム(たとえば、テストされていないMac-'posix'またはembedded ARM systems)。より多くのPythonicは、すべての既知のシステムを列挙せず、関連する可能性のあるプロパティをテストします(たとえば、システムのエンディアンネスは重要ですが、重要でないマルチプロセッシングプロパティと見なされます)。

  • os.nameは、osモジュールを正しく使用するための十分な解像度です。可能な値は、「posix」、「nt」、「os2」、「ce」、「Java」または「riscos」で、Python 2.7、一方、 'posix'、 'nt'、 Python 3.4。

  • sys.platformはより優れた解像度です。 「linux2」はLinuxカーネルバージョン2.xxまたは3を意味するため、if sys.platform.startswith('linux')イディオムを使用することをお勧めします。古いカーネルは現在使用されていません。 In Python 3.3はすべてLinuxシステムの単純な「linux」です。

「Mac」および「Java」システムの詳細がわからないため、非常に優れたメソッドplatform.system()の結果を分岐に使用することはできませんが、platformモジュールの利点を使用してメッセージとエラーログ。

10
hynekcer

プラットフォームモジュールはおそらく新しいコードに適していると思います。他は前に存在していました。それは進化であり、他のものは後方互換性のために残っています。

2
Keith