2012-10-12 11 views
15

私はurllib(python3)用の小さなラッパーを書いています。それがあればでモジュールをインポートする適切安全ですか?Python - インポートする場合

if self.response_encoding == 'gzip': 
    import gzip 

このコードについてのPEPは見つかりませんでした。しかし、それは私を悩ます。

+1

ちょうどそれがインポートされていない場合 – njzk2

+0

はいそうです、このパッケージから任意の関数を呼び出すしないようにしてください。どうしてそれはあなたを悩ませるのですか? –

+0

私は尋ねたかったと確信していました。多分私は 'worried'という言葉を使うべきでしょう。英語は母国語ではありません。 –

答えて

19

PYT:標準ライブラリ(osのソースコードのいくつかは、以下)でos.path hon標準ライブラリはそれを使用しているので、最も適切かつ安全です。優れた例えばos module sourceを参照してください。

if 'posix' in _names: 
    name = 'posix' 
    linesep = '\n' 
    from posix import * 
    try: 
     from posix import _exit 
    except ImportError: 
     pass 
    import posixpath as path 
    import posix 
    __all__.extend(_get_exports_list(posix)) 
    del posix 

それはPythonで条件付きで輸入・モジュールにはかなり一般的です。代わりにifの、あなたはあまりにもtry:/except ImportError:組み合わせ頻繁に表示されます:ここで

try: 
    from subprocess import check_output 
except ImportError: 
    # Python 2.6 and before 
    def check_output(*popenargs, **kwargs): 
     from subprocess import Popen 
     if 'stdout' in kwargs: 
      raise ValueError('stdout argument not allowed, it will be ' 
          'overridden.') 
     process = Popen(stdout=PIPE, *popenargs, **kwargs) 
     output, unused_err = process.communicate() 
     retcode = process.poll() 
     if retcode: 
      cmd = kwargs.get("args") 
      if cmd is None: 
       cmd = popenargs[0] 
      raise CalledProcessError(retcode, cmd) 
     return output 

を、私たちは基本的にifテストの道徳的同等のものを使用します。あなたはcheck_outputをインポートすることができた場合は、そう、そうでない場合は、完全な機能を定義しますここに。

import文は、単に再結合コードの外部一片のローカル名にあります。 if制御フローを使用してインポートを制御することは、その点に関してifステートメントで変数を割り当てることと変わりありません。どちらの方法でも定義されていない名前を使用しないようにする必要があります。

+0

+1 - 'try/except ImportError'はこの質問にも私の最初の本能でした。 – mgilson

3

確かに問題ありません。常に実行したくない初期化コードがモジュールにある場合にも必要です。

8

これは実際には合理的に一般的なイディオムです。あなたは時々、異なるモジュール間で選択することが表示されます:

if system == 'linux': 
    import linuxdeps as deps 
elif system == 'win32': 
    import win32deps as deps 

その後、linuxdepswin32depsの両方を想定して同じ機能を持っている、あなたはそれを使用することができます。

deps.func() 

これはさえ取得するために使用されます

if 'posix' in _names: 
    name = 'posix' 
    linesep = '\n' 
    from posix import * 
    try: 
     from posix import _exit 
    except ImportError: 
     pass 
    import posixpath as path 

    import posix 
    __all__.extend(_get_exports_list(posix)) 
    del posix 

elif 'nt' in _names: 
    name = 'nt' 
    linesep = '\r\n' 
    from nt import * 
    try: 
     from nt import _exit 
    except ImportError: 
     pass 
    import ntpath as path 

    import nt 
    __all__.extend(_get_exports_list(nt)) 
    del nt 
1

安全ですか?はい。 Martijin's answerは公式のPythonがこれを使用していると指摘しています。

これは適切ですか?依存します。 Python performance docsは、たとえPythonが同じモジュールをインポートすることを避けることができますが、依然としてオーバーヘッドがあることを指摘しています。

だから、あなたはif文がどれほど頻繁に真であるか自分自身に尋ねるべきだと思います。非常に頻繁に発生する場合は、オーバーヘッドが大きくなります。ファイルの先頭にインポートする必要があります。頻繁ではない場合は、if文をインポートする方が賢明です。

関連する問題