私はいつもこの方法を使ってきました:
from sys import argv
そして、argv
をargvだけで使用します。しかし、これを使用する慣習があります:
import sys
sys.argv
によるargvの使用
2番目の方法では、コードを自己文書化し、I(本当に)を使用します。しかし、私が最初の方法を好む理由は、モジュール全体をインポートするのではなく、必要な関数のみをインポートしているため高速であるためです(pythonは、インポートに時間を浪費します) 。argvが必要なだけで、sysの他のすべての関数は役に立たないことに注意してください。
だから私の質問です。最初の方法は本当にスクリプトを高速にしますか?どの方法が最も好ましいですか?どうして?
モジュールをインポートしても無駄はありませんanything;モジュールは常に完全が(_sys.modules
_マッピングに)インポートされるため、_import sys
_または_from sys import argv
_を使用するかどうかに関係なく、オッズはありません。
2つのステートメントの唯一の違いは、バインドされる名前です。 _import sys
_は、名前sys
をモジュールにバインドします(so sys
-> _sys.modules['sys']
_)。一方、_from sys import argv
_は、モジュール内に含まれる属性を直接指しているargv
をバインドします(so argv
) -> _sys.modules['sys'].argv
_)。 sys
モジュールの残りの部分は、モジュールの他のものを使用するかどうかに関係なく、そのまま残ります。
また、2つのアプローチの間にパフォーマンスの違いはありません。はい、_sys.argv
_は2つのことを調べる必要があります。グローバル名前空間でsys
を検索し(モジュールを検索)、次に属性argv
を検索する必要があります。そして、はい、_from sys import argv
_を使用すると、属性への直接参照が既にあるため、属性の検索をスキップできます。ただし、import
ステートメントは引き続きこの処理を行う必要があります。インポート時に同じ属性を検索します。argv
onceを使用するだけで済みます。ループでargv
を何千回も使用する必要がある場合、おそらく違いが生じる可能性がありますが、この特定のケースでは実際には違いはありません。
その場合、どちらか一方の選択は、代わりにコーディングスタイルに基づく必要があります。
largeモジュールでは、確かに_import sys
_を使用します。コードのドキュメントが重要であり、_sys.argv
_を大きなモジュールのどこかに使用すると、argv
だけで参照するよりも、参照している内容が明確になります。
argv
を使用する唯一の場所が_'__main__'
_ブロック内にあり、main()
関数を呼び出す場合、それについて幸せだと感じた場合は、必ず_from sys import argv
_を使用してください。
_if __name__ == '__main__':
from sys import argv
main(argv)
_
私はまだ_import sys
_を自分で使用します。すべてが等しい(そして、正確には、パフォーマンスの観点から言えばand書き込みに使用される文字数)、それは私にとっては目に優しいだけです。
何かをインポートする場合elseを一緒に使用すると、おそらくパフォーマンスが発揮されます。ただし、たとえば重要なループで、モジュールで特定の名前を使用する場合のみ何度もを使用します。ただし、ローカル名を(関数内で)作成すると、さらに高速になります。
_ import somemodule
def somefunction():
localname = somemodule.somefunctionorother
while test:
# huge, critical loop
foo = localname(bar)
_
_import module
_ではなく_from module import function
_を使用することには、2つの理由があります。
最初は名前空間です。関数をグローバル名前空間にインポートすると、名前の衝突が発生する可能性があります。
2つ目は、標準モジュールに関連するものではありませんが、特に開発中は、独自のモジュールにとって重要です。モジュールのreload()
のオプションです。このことを考慮:
_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
_よりインタープリターの作業が少ないです。
私の意見では、通常の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()
例外として、私は常にfrom module import something
を扱うときの表記__future__
モジュール。 Python 2、.
from __future__ import unicode_literals
from __future__ import print_function
私が使う from import
s読みやすさを向上させるたびに。たとえば、私は好みます(セミコロンはここでスペースを節約するためだけです):
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
sを使用します。
import sys
sys.argv; sys.stderr; sys.exit()
または、名前が汎用的すぎて名前空間の外では意味をなさない場合:
import json
json.loads(foo)
from json import loads
loads(foo) # potentially confusing
import sys
とfrom sys import agrv
はどちらもsys
モジュール全体をインポートしますが、後者は名前バインディングを使用するため、残りのコードはargv
モジュールのみにアクセスできます。
一部の人々にとっては、これはあなたが明示的に述べた機能にアクセスできるようにするだけなので、これが好ましいスタイルです。
ただし、名前の競合が発生する可能性があります。 argv
という名前の別のモジュールがある場合はどうなりますか?関数を明示的にインポートしてfrom sys import argv as sys_argv
で名前を変更することもできます。これは、明示的なインポートに対応し、名前空間の衝突を起こしにくい規則です。
私は最近この質問を自分に問いかけました。さまざまな方法で時間を計った。
ライブラリをリクエストする
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
beautifulsoupライブラリ
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
あるパフォーマンスにわずかな違いがあるように思えます。