web-dev-qa-db-ja.com

「import *」は正確に何をインポートしますか?

Pythonでは、import *は正確に何をインポートしますか?含まれているフォルダーにある__init__.pyをインポートしますか?

たとえば、from project.model import __init__を宣言する必要があるか、またはfrom project.model import *で十分ですか?

44
ensnare

from xyz import *の "利点"は、他の形式のインポートとは異なり、指定されたモジュールからeverything(まあ、ほとんど... [(a)を参照)すべて)をインポートすることです。現在のモジュール。これにより、インポートされたモジュールのさまざまなオブジェクト(変数、クラス、メソッド...)を、モジュールの名前を前に付けずに使用できます。例えば

>>> from math import *
>>>pi
3.141592653589793
>>>sin(pi/2)
>>>1.0

ただし、(現在のネームスペースに*をインポートする)この方法は推奨されません

  • 名前空間の衝突の機会を提供します(たとえば、インポート前に変数名piがあった場合)
  • インポートされるオブジェクトの数が多い場合、効率が悪い場合があります
  • 変数/メソッド/クラスの起源を明示的に文書化することはありません(コードの将来の訪問のためにプログラムのこの「自己文書化」を持つことは素晴らしいことです)

したがって、通常、このインポートのプラクティスはアドホックテストなどに限定されます。 @Denilson-Sá-Maiaが指摘したように、(pygameなど)などの一部のライブラリには、最も一般的に使用されるすべての定数と関数が定義されたサブモジュールがあり、そのようなサブモジュールは効果的にdesignedimport *でインポートされます。これらの特別なサブモジュールを除いて、それ以外の場合は...の方が望ましいです:

少数のオブジェクトのみを明示的にインポートする

>>>from math import pi
>>>pi
>>>3.141592653589793
>>> sin(pi/2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sin' is not defined

またはモジュールを独自の名前空間でインポートします(特に、これが長い名前であり、プログラムがそのオブジェクトを何度も参照する場合はそのエイリアス)

  >>>import math
  >>>math.pi
  >>>3.141592653589793
  etc..


  >>>import math as m  #bad example math being so short and standard...
  >>>m.pi
  >>>3.141592653589793
  etc..

このトピックに関する Pythonドキュメントを参照してください

(a)具体的には、from xyz import *でインポートされるもの
xyzモジュールが__all__変数を定義する場合、このシーケンスで定義されるすべての名前をインポートします。そうでない場合は、アンダースコアで始まる名前を除くすべての名前をインポートします。

多くのライブラリにはサブモジュール 。たとえば、標準ライブラリurllibには、urllib.requesturllib.errorsurllib.responseなどのサブモジュールが含まれます。一般的な混乱点は、

from urllib import *

これらすべてのサブモジュールをインポートします。 そうではありません:たとえば、from urllib.request import *などを使用してこれらを個別に明示的にインポートする必要があります。これは、たまたまimport *、プレーンimportはサブモジュールもインポートしません(しかし、もちろん、"everything"の省略形である*は、人々を誤解させる可能性がありますすべてのサブモジュールと他のすべてがインポートされることになります)。

51
mjv

モジュール(またはパッケージ)の__all__属性にリストされている名前はすべて(現在のネームスペースに)インポートします。このような属性、_で始まらないすべての名前が欠落しています。

他の回答が示唆するように、プログラムで使用しないでください

GoogleのPythonスタイルガイド によると、これまでにのみインポートすることをお勧めしますモジュールnotモジュール内からのクラスまたは関数(または他の名前):これを厳密に守ることで、明確さと正確さを実現し、「モジュール内から」のものをインポートするときに生じる可能性のある微妙なトラップを回避します。

パッケージ(またはその中からのもの)をインポートすると、パッケージの__init__.pyが本質的に読み込まれて実行されます。このファイルはパッケージの本体を定義します。ただし、現在のネームスペースの名前__init__はバインドしません(そのため、この意味ではその名前はインポートされません)。

12
Alex Martelli

はい、そうです。 everything(つまり、プライベート変数ではありません。つまり、名前が_または__で始まる変数)をインポートします。ローカル名前空間の汚染を避けるため、「 Pythonでモジュールを正しくインポートする 」に従って使用しないようにしてください。

それで十分ですが、一般的には、「 nderstanding python imports 」に従って、すでにimport project.modelをインポートする__init__.pyを実行する必要がありますが、使いすぎると言葉が長すぎるか、後で使用するときにいくつかのキーストロークを保存するにはimport project.model as pmまたはimport project.model as modelになります。

「インポート*」インポートとは正確には何ですか? 」のアレックスのアドバイスに従ってください。

4
Esteban Küber

project.modelがパッケージの場合、import project.modelによって参照されるモジュールは.../project/model/__init__.pyからのものです。 from project.model import *は、__init__.pyのネームスペースからすべてをネームスペースにダンプします。モデル内の他のモジュールでは自動的に何もしません。推奨されるスタイルは、__init__.pyが何も含まないことです。

import *を使用したことはありません。コードが判読不能になり、保守不能になります。

3
Mike Graham

モジュールからどの星/アスタリスク(*)がインポートされたかを確認する良い方法は次のとおりです。

before = dir()
from math import *
after = dir()
print(set(after) - set(before))

戻り値:

{'modf', 'pow', 'erfc', 'copysign', 'sqrt', 'atan2', 'e', 'tanh', 'pi', 'factorial', 'cosh', 'expm1', 'cos', 'fmod', 'frexp', 'log', 'acosh', 'sinh', 'floor', 'isclose', 'lgamma', 'ceil', 'gcd', 'ldexp', 'hypot', 'radians', 'atan', 'isnan', 'atanh', 'before', 'isinf', 'fabs', 'isfinite', 'log10', 'nan', 'tau', 'acos', 'gamma', 'asin', 'log2', 'tan', 'degrees', 'asinh', 'erf', 'fsum', 'inf', 'exp', 'sin', 'trunc', 'log1p'}

私は自分のモジュールで作業していましたが、すべてを明示的にインポートしましたが、インポートするもののリストが長すぎました。そのため、このメソッドを使用して*がインポートしたもののリストを取得する必要がありました。

2
cardamom

問題のモジュール(あなたの場合はproject.model)が__all__という名前のスティングのリストを定義している場合、そのリスト内のすべての名前付き変数がインポートされます。そのような変数がない場合は、すべてをインポートします。