私はいつもこの方法を使用しています:

from sys import argv 

そしてargv argv と一緒に使用します。ただし、これを使用する規則があります:

import sys 

およびsys.argv

2番目の方法では、コードが自己文書化され、(本当に)準拠します。しかし、私が最初の方法を好む理由は、モジュール全体をインポートするのではなく、必要な関数のみをインポートするため、高速であるためです(Pythonがインポートに時間を浪費する、より多くの役に立たない関数が含まれています)。必要なのはargvだけであり、sysの他のすべての関数は役に立たないことに注意してください。

つまり、私の質問はそうです。最初の方法は本当にスクリプトを高速にしますか?どの方法が最も好ましいですか?なぜですか?

コメント

回答

モジュールをインポートしても何も無駄になりません;モジュールは常に完全ですは(sys.modulesマッピングに)インポートされるため、import sysまたはfrom sys import argvはオッズを作成しません。

2つのステートメントの唯一の違いは、バインドされる名前です。import sysは名前をバインドしますsysをモジュールに(つまり、sys-> sys.modules["sys"])、from sys import argvはバインドします別の名前argvは、モジュール内に含まれる属性をまっすぐ指します(つまり、argv-> sys.modules["sys"].argv)。残りの部分e sysモジュールは、モジュールの他のものを使用するかどうかに関係なく、引き続き存在します。

2つのアプローチの間にパフォーマンスの違いもありません。はい、sys.argvは2つのことを調べる必要があります。グローバル名前空間でsysを検索し(モジュールを検索)、次に属性argvを検索する必要があります。はい、from sys import argvを使用すると、属性への直接参照がすでにあるため、属性の検索をスキップできます。ただし、importステートメントは引き続きその作業を行う必要があり、インポート時に同じ属性を検索します。「argv 一度。ループでargvを何千回も使用する必要がある場合は、おそらく違いが生じる可能性がありますが、この特定のケースでは実際には違いがありません。 。

その場合、どちらを選択するかは、代わりにコーディングスタイルに基づく必要があります。

large モジュール内、私は確かにimport sysを使用します。コードのドキュメントが重要であり、大きなモジュールのどこかでsys.argvを使用すると、argvよりもはるかに明確になります。

argvを使用する唯一の場所が"__main__"ブロック内にある場合main()関数、それについて満足している場合は、必ずfrom sys import argvを使用してください:

if __name__ == "__main__": from sys import argv main(argv) 

I 「まだimport sysを自分で使用しています。すべてが同じです(正確には、パフォーマンスと書き込みに使用される文字数の点で ) 、それは私にとっては簡単です。

他のものをまとめてインポートする場合は、おそらくパフォーマンスが影響します。ただし、特定の名前を使用する場合に限ります。モジュールは何度も、たとえばクリティカルループで行われます。ただし、ローカル名(関数内)の作成はさらに高速になります:

 import somemodule def somefunction(): localname = somemodule.somefunctionorother while test: # huge, critical loop foo = localname(bar) 

コメント

  • 最上位パッケージ内のサブパッケージ/モジュールの1つの属性を公開するサブパッケージまたはモジュールを含むパッケージがある場合もあります。 from...importを使用すると、package.subpackage_or_module.attributeではなくpackage.attributeを実行できます。パッケージ内に論理的または概念的なグループ化がありますが、パッケージのユーザーにとってもう少し便利なものにしたいです。 (numpyはこのようなことをしていると思います。)
  • djangoには、from django.core.management.base import BaseCommandの方が優れており、他のもの(特にimport django)を使用すると、コードが読み取れなくなります。ですから、私はこの答えが好きですが、慣例が裸のインポートに違反することであるいくつかのライブラリ(そして特にいくつかのフレームワーク)があると思います。いつものように、与えられた状況で何が最善かについてあなたの判断を使用してください。しかし、明示的な側で誤りを犯します(言い換えれば、私はほとんどの部分に同意します)。
  • @JAB:import ... asを使用してパッケージを見つけることができます。別の名前:import package.subpackage_or_module as shortnamefrom parent import subは基本的に同じことを行います。
  • so wether you use import sys or from sys import argv makes no oddsこれはIDLEには当てはまらないようです。モジュールをインポートするだけではその関数はインポートされず、IDLEシェルで呼び出すことができるのは< module >。< function > name
  • @Suncatcher:私の答えを完全に読んでください。あなたが引用する文は、どの名前がバインドされているかではなく、どれだけインポートされているかについて話します。その’は回答の他の場所で説明されています。

回答

from module import functionではなくimport moduleを使用することに賛成する2つの理由があります。

最初は名前空間です。関数をグローバル名前空間にインポートすると、名前の衝突のリスクがあります。

2つ目は、標準モジュールには関係ありませんが、特に開発中は、独自のモジュールにとって重要です。モジュール。これを考慮してください:

from module import func ... reload(module) # func still points to the old code 

一方

import module ... reload(module) # module.func points to the new code 

速度については。 。

モジュール全体をインポートするのではなく、必要な関数のみをインポートします(これには、Pythonがインポートに時間を浪費する無駄な関数が含まれています)

モジュールをインポートする場合でも、モジュールから関数をインポートする場合でも、Pythonはモジュール全体を解析します。どちらの方法でも、モジュールがインポートされます。 「関数のインポート」は、関数を名前にバインドすることに他なりません。実際、import moduleは、from module import funcよりも通訳者の作業が少なくて済みます。

コメント

  • reload()はPython2に組み込まれていました。これはPython3には当てはまりません。
  • 循環インポートの依存関係にも影響があると思いましたか?

回答

読みやすさが向上するたびに、from importを使用します。たとえば、私は好みます(セミコロンはここでスペースを節約するためだけのものです):

from collections import defaultdict from foomodule import FooBar, FooBaz from twisted.internet.protocol import Factory defaultdict(); FooBar(); FooBaz(); Factory() 

代わりに:

import collections import foomodule import twisted.internet.protocol collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz() twisted.internet.protocol.Factory() 

後者は冗長な情報がたくさん含まれているため、私にとっては読み取り(および書き込み)が困難です。また、モジュールのどの部分を使用しているかを事前に知っておくと便利です。

ロットを使用している場合は、通常のimportを使用します。モジュールからの短い名前の例:

import sys sys.argv; sys.stderr; sys.exit() 

または、名前が非常に一般的で、名前空間の外では意味をなさない場合:

import json json.loads(foo) from json import loads loads(foo) # potentially confusing 

コメント

  • これが私のお気に入りの回答です。 ‘暗黙的よりも明示的の方が優れている’は、読みやすさ、シンプルさ、DRYと競合することがあります。特にDjangoのようなフレームワークを使用する場合。

回答

私の意見では通常のimportは読みやすさを向上させます。 Pythonコードを確認するとき、指定された関数またはクラスが使用されている場所からどこから来ているかを確認するのが好きです。モジュールの一番上までスクロールしてその情報を取得する手間が省けます。

長いモジュール名については、asキーワードを使用して短くします。エイリアス:

import collections as col import foomodule as foo import twisted.internet.protocol as twip my_dict = col.defaultdict() foo.FooBar() twip_fac = twip.Factory() 

例外として、iv id =を扱うときは、常にfrom module import something表記を使用します。 “c58a4bc552”>

モジュール。 Python 2でデフォルトですべての文字列をユニコードにしたい場合は、別の方法でそれを行うことはできません。たとえば、

from __future__ import unicode_literals from __future__ import print_function 

コメント

  • アーメン!” import as “は勝利の組み合わせです:-)

回答

ただし、import sysおよびfrom sys import agrv両方ともsysモジュール全体をインポートします。後者は名前バインディングを使用するため、残りのコードはargvモジュールのみにアクセスできます。

明示的に指定した関数にのみアクセスできるため、これが推奨されるスタイルです。

ただし、名前の競合が発生する可能性があります。

?関数を明示的にインポートし、from sys import argv as sys_argvで名前を変更することもできます。これは、明示的なインポートに適合し、名前空間を指定する可能性が低い規則です。衝突。

コメント

  • では、if sys_argv:は?私は2番目のステートメントが何を意味するかを知っていますが、奇妙なインポートに戻ることなく、最初のフォームが何を意味するのかわかりません。

回答

最近、この質問を自分に問いかけました。さまざまなメソッドの時間を計りました。

リクエストライブラリ

def r(): import requests return "hello" timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop def rg(): from requests import get return "hello" timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop 

美しいスープライブラリ

def bs(): import bs4 return "hello" timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop def be(): from bs4 import BeautifulSoup return "hello" timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop 

jsonライブラリ

def js(): import json return "hello" timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop def jl(): from json import loads return "hello" timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop 

sysライブラリ

def s(): import sys return "hello" timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop def ar(): from sys import argv return "hello" timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop 

パフォーマンスにわずかな違いがある と私は思います。

コメント

  • 属性ルックアップを追加しています。 import modulefrom module import nameを正しく比較するには、その名前ルックアップをimport module追加します。

の場合。例えば。sys.argvの行をarテストなどに追加します。実行される作業はわずかに異なるバイトコードが生成され、異なるコードパスが実行されるため、異なります。

  • 回答の違いに直接対処していることに注意してください。 import sysを使用する場合とsys.argvをループで数千回使用する場合と、from sys import argv次に、argvのみを使用します。ただし、’ tはしません。モジュールのグローバルレベルで一度行うことについては、タイミングの微視的な違いではなく、読みやすさを最適化する必要があります。
  • ああ!そして、私は何かに取り組んでいると思いました! :)私はあなたの答えをざっと見ただけです。あの銃に飛び乗ったようだ。謙虚になって良かったです。
  • 回答

    公開されたコードフラグメントを見て、モジュール全体をインポートし、module.functionは、少なくとも標準モジュールでは、ほぼ標準です。唯一の例外はdatetime

    from datetime import datetime, timedelta 

    のようですので、datetime.now()datetime.datetime.now()ではなく/ div>。

    パフォーマンスが心配な場合は、いつでも(たとえば)

    次に、モジュールルックアップがすでに実行されているため、パフォーマンスが重要なコードを実行します。ただし、これは関数/メソッドで機能しますが、ほとんどのIDEは混乱し、(たとえば)変数に割り当てられたときに関数のソースリンク/署名を表示しません。

    回答

    次のようなことをした場合に追加したい

    from math import sin 

    (またはsysposixなどの他の組み込みライブラリ)、sinはモジュールのドキュメントに含まれている(つまり、>>> help(mymodule)または$ pydoc3 mymoduleを実行する場合。これを回避するには、次を使用してインポートします。

    import math from math import sin as _sin 

    PS:組み込みライブラリは、Cコードからコンパイルされ、Pythonに含まれているライブラリです。argparseosioは組み込みパッケージではありません

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です