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


102

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

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

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

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

ように思えるsys.platformよりも具体的であるos.nameあなたが区別できるように、win32からcygwin(だけとは対照的にはnt)、およびlinux2からdarwin(だけではなくて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ので、この質問は特に緊急ではありませんが、これについての明確化に感謝します。


15
将来の互換性sys.platform.startswith('linux')sys.platform == 'linux2'ためにの代わりに使用
jfs

回答:


67

少しソースコードに分割しました。

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

  • sys.platform ビルド構成中にコンパイラー定義として指定されます。
  • os.name特定のOSの特定のモジュールが利用可能かどうかをチェックし(例えばposixnt、...)
  • platform.system()実際に実行さunameれ、実行時にシステムタイプを決定するために他のいくつかの機能が実行される可能性があります。

私のおすすめ:

  • os.nameposix準拠のシステムかどうかを確認するために使用します。
  • sys.platformLinux、Cygwin、Darwin、Atheosなどであるかどうかを確認するために使用します。
  • platform.system()他のソースを信じない場合に使用します。

2
私はより多くの研究を行い、ここに詳細な答えがあります:stackoverflow.com/a/58071295/207661
Shital Shah

20

との間に細い線の違いが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タプルを返します。タプルには5つの文字列(sysname、nodename、release、version、machine)が含まれています。一部のシステムでは、ノード名が8文字または先頭のコンポーネントに切り捨てられます。ホスト名を取得するより良い方法は、socket.gethostname()またはsocket.gethostbyaddr(socket.gethostname())です。

Availability: recent flavors of Unix.

11

sys.platformドキュメントから:

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

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

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

platform.system()それはいくつかのソースから取得する可能性があることを正規化した値を返します:os.uname()sys.platformverコマンド(Windowsの場合)。


10

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

  • os.nameは、osモジュールを正しく使用するための十分な解像度です。Python 2.7では、「posix」、「nt」、「os2」、「ce」、「java」、「riscos」のいずれかの値を使用できますが、Python 3.4以降では「posix」、「nt」、「java」のみが使用されます。

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

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


os.name可能な戻り値は'posix''nt''java'に応じてPythonの3ドキュメント。参照:プラットフォームモジュールのドキュメントを。私は信じないし'riscos''os2'からの可能な戻り値os.nameです。それらはからの戻り値sys.platformである可能性がありますPythonの3 sys.platformのドキュメントは、網羅的であるように表示されません。
afeique

1
@afeique:新しいPythonの回答を更新しましたが、その時点で正しかったです。Python 3.3-os.name(当時の最新バージョン)を参照してください。Python 2.7は引き続きサポートされており、 'riscos'はその可能な値です。
hynekcer

@hynekcerに感謝します。Pythonのバージョン番号を追加する編集に感謝します。Python 3.3以降に変更されたことに気づかなかったことをお詫びします。ドキュメントの異なるバージョンを熟読せず、Python 3の動作はos.nameバージョン間で一貫していると大まかに想定しました。また、2.7のドキュメントを再確認しませんでしたが、あなたが正しいことはわかっています。
afeique 2018

3

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


7
Python開発者にこれを確認してもらうことはできるでしょうか。たぶん、プラットフォームモジュールを開発した人であっても。
ztangent 2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.