この点についてはあまり明確ではありません。独自の個別のモジュールである.pyファイルの束があるとします。
各.pyファイルがそのクラスを使用するときに他のファイルをインポートする必要があるのはなぜですか?それともそうですか?他の言語(Javaなど)は、同じディレクトリ内のクラス/ファイルを参照するときにインポートする必要がないことを確信していたからです。私は間違っているかもしれません。
簡単に言えば、それはそれが設計された方法です。あなたはJavaの反例として言及しました-Java言語の設計者はクラスローディングをいくぶん暗黙的にしたかったので、ClassNotFound
をスローする前に同じディレクトリをチェックしました。それ以外ではPythonと同じように、資格を得る必要があります。
Tom Andersonが言ったように、CはPythonと同じことを行い、それはコンパイルされた言語です。おそらく、言語の解釈された性質は、最終的な決定(パフォーマンス、明示性など)と関係があるかもしれませんが、最終的には開発者次第です。
pythonは解釈されるため、インポートしたすべてのものがプロンプトで使用できます。Java(およびC++)には、関数のみを検索して含めることができるコンパイルとリンクのステップがあります。使用されている
すべてが自動的にインポートされた場合、数千の関数と変数が存在し、衝突することなく何かを入力することは不可能です。
編集:Okコンパイルされたか解釈されるだけではありません。Pythonは「バッテリーを含む」言語として意図されています-ほとんどすべてを実行できるライブラリがあります使用するのはほんの一部なので、必要なものだけを含めるように整理する方法が必要です。
ライブラリ全体をインポートしてJavaのような完全修飾名を保持するか、特定の関数(またはすべての関数)をローカル名前空間にインポートできるため、構文からのインポートは賢いです
>>>import math
>>> math.sin(0) #no confusion with any other 'sin'
>>> from math import sin # or import *
>>> sin(0) # makes equations with sin shorter and simpler
2番目の理由は、Pythonなどの動的言語では特に重要です。変数を使用する前に変数を定義する必要がないため、sin
が数学関数またはインタープリター内の変数である場合、環境がうまく機能しません。
あなたがこのコードをPythonで持っていると想像してください:
foo = MyObject()
fo.bar()
明らかに、タイプミスがあり、fo
はfoo
でした。今pythonは言う:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'fo' is not defined
しかし、暗黙的なクラスローディングでは、それは言うかもしれません:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named fo
混乱するでしょう。さらに悪いことに、たまたまモジュールの名前である変数名のスペルを間違えた場合、そのモジュールを変数であるかのように処理しようとすると、さらに混乱するエラーが発生します。 Pythonは、何かがクラス名であるか、オブジェクトであるか、何かであるかどうかを判断できません。
一方、Javaは、特定の識別子がクラスまたは他の何かを参照しているかどうかを構文から判断できると思います。したがって、適切なエラーメッセージが表示されても問題はありません。
全体的に、それはPython暗黙ではなく明示的であるという哲学に適合します。自動的にインポートするのではなく、明示的にモジュールをインポートする方が良いと考えています。エラーメッセージの問題は、決定。
一部のユーザーは、暗黙的なインポートには実行時のコストが大きいと示唆しています。私はそうは思いません。何が起こるかは次のようなものです:
暗黙的なモジュールの読み込みをサポートするために、次のことができます。
import foo
モジュールを初めて使用するときは、最初に他の辞書を検索する必要があるため、少し時間がかかります。しかし、それは初めてのことであり、プログラム全体の実行時間の点で重要であってはなりません。
変数名にスペルミスがある場合は、かなりのコストがかかります。 pythonが発生すると、モジュールを見つけるためにディスクを読み取るのに時間がかかります。しかし、それが起こったとしても、プログラムはトレースバックで死にかけようとしており、パフォーマンスは大きな問題ではありません。
PythonとJavaの間にはいくつかの重要な違いがあります。Javaには「ファイルごとに1つのクラス」というルールがありますが、Pythonまた、Python=のすべてがクラスであるとは限りません。
そのため、モジュールにはクラス、関数、および単純な古い変数を含めることができます-通常はすべて何らかの方法で関連しています(random
のランダム関数、math
の数学ルーチン、string
の文字列定数など)。
特定のモジュールからクラス/関数/変数にアクセスする場合は、最初にそれをインポートする必要があります。
なぜこれが良いことなのですか?
math.sin
および独自のsin
関数)Pythonの最も重要な概念の1つは、名前空間の概念です(import this
プロンプトで、他のメンバーが何であるかを確認します。名前空間が他の言語にも存在することは知っていますが、Pythonでは、現在のモジュールで定義されている現在の名前空間にしかアクセスできません。他の識別子にアクセスするには、それらを現在の名前空間にインポートします。それらを含むモジュール(import foo
構文)または名前自体(from foo import bar
)。