ProgrammingPython 開発者

Pythonにおける名前空間(namespace)やモジュールの特性について説明してください。インポートはどのように機能し、大規模なプロジェクトで名前の衝突を避けるにはどうすればよいですか?

Hintsage AIアシスタントで面接を突破

回答。

Pythonにおける名前空間(namespace)は、名前とオブジェクトを紐付ける辞書です。名前空間のレベルには、ローカル、グローバル、ビルトインがあります。モジュールはコードを整理するための別の名前空間です。インポート時にPythonは各モジュールのための新しい名前空間を作成します。

インポートの動作

  • import module — モジュールをインポートし、module.nameを介してオブジェクトにアクセスします。
  • from module import name — モジュールからオブジェクトを直接現在の名前空間にインポートします(名前の衝突のリスクがあります)。
  • as — エイリアスを指定できます。

名前の衝突を避けるために:

  • 明示的なモジュールインポート(import mymodule)を使用し、アスタリスク(from... import *)を避けます。
  • パッケージを使ってプロジェクトを整理します(__init__.pyを含むディレクトリ)。
  • ユニークで意味のある名前を使います;
  • エイリアス(import module as m)を使用します。

構造の例

project/
  package/
    __init__.py
    module1.py
    module2.py
import package.module1 from package.module2 import function as fn

トリックのある質問。

質問: モジュールを二度インポートすることの違いは何ですか?モジュールのコードは再び実行されますか?

回答: いいえ。最初のインポート時にモジュールは実行され、その結果はsys.modulesにキャッシュされます。再インポートはすでにロードされたモジュールオブジェクトを返し、そのコードは再度実行されません。

# module.py print('Hello!') # main.py import module # Hello!と出力されます import module # 何も出力されません

このテーマの細かい違いを知らないことによる実際のエラーの例。


事例

開発者たちは複数のモジュールでfrom settings import *を使用した結果、設定に変更を加えるとローカル変数が予期せず「上書き」され、発見が困難なバグを引き起こしました。

事例

大規模プロジェクトでは、異なるチームが同じ名前のモジュール(例:utils.py)を作成しました。統合段階で、「同じ」名前のモジュールが互いに「置き換え」合い、予期しない動作や複雑なバグを引き起こしました。

事例

あるライブラリでは、新しい設定でモジュールを「ホット再インポート」しようとしましたが、すでにインポートされた他のモジュールがオブジェクトの古い参照を保持しており、アプリケーションのすべての部分で変更が適用されませんでした。