[解決済み】Python 3での相対インポート
質問
同じディレクトリにある別のファイルから関数をインポートしたいのですが、どうすればいいですか?
でうまくいくこともあります。
from .mymodule import myfunction
が、時々出る。
SystemError: Parent module '' not loaded, cannot perform relative import
で動作することもあります。
from mymodule import myfunction
を取得することもあります。
SystemError: Parent module '' not loaded, cannot perform relative import
このロジックは理解できませんし、説明も見つかりませんでした。これは完全にランダムに見えます。
どなたか、どういう理屈か説明してください。
どのように解決するのですか?
<ブロッククオート残念ながら、このモジュールはパッケージの中にある必要があり、また、このモジュールは はスクリプトとして実行可能である必要があります、時々。どのようにしたら を実現できますか?
こんなレイアウトはよくありますよね...。
main.py
mypackage/
__init__.py
mymodule.py
myothermodule.py
...を使って
mymodule.py
このように...
#!/usr/bin/env python3
# Exported function
def as_int(a):
return int(a)
# Test function for module
def _test():
assert as_int('1') == 1
if __name__ == '__main__':
_test()
...a
myothermodule.py
このように...
#!/usr/bin/env python3
from .mymodule import as_int
# Exported function
def add(a, b):
return as_int(a) + as_int(b)
# Test function for module
def _test():
assert add('1', '1') == 2
if __name__ == '__main__':
_test()
...そして
main.py
こんな感じで...
#!/usr/bin/env python3
from mypackage.myothermodule import add
def main():
print(add('1', '1'))
if __name__ == '__main__':
main()
を実行すると、正常に動作します。
main.py
または
mypackage/mymodule.py
を指定すると失敗します。
mypackage/myothermodule.py
相対インポートのため...
from .mymodule import as_int
実行の仕方は
python3 -m mypackage.myothermodule
...しかし、これはやや冗長で、次のような shebang 行とうまく組み合わせられません。
#!/usr/bin/env python3
.
この場合の最も単純な修正方法は、名前を想定して
mymodule
がグローバルに一意である場合、相対インポートの使用を避け、単に...を使用することです。
from mymodule import as_int
...ただし、一意でない場合、あるいはパッケージの構造がより複雑な場合は、パッケージディレクトリを含むディレクトリを
PYTHONPATH
と、こんな感じです。
from mypackage.mymodule import as_int
また、「箱から出してすぐに使える」ようにしたい場合は
PYTHONPATH
を、まずこのようにコードで記述します...
import sys
import os
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(SCRIPT_DIR))
from mypackage.mymodule import as_int
ちょっと面倒ですが、その理由のヒントは 電子メール Guido van Rossum氏によって書かれた...
私は、この件と、その他に提案されている
__main__
を使用します。唯一のユースケースは、たまたま実行したスクリプトが モジュールのディレクトリの中に住んでいること。 アンチパターン 私の考えを変えさせるには、以下のことを納得させなければなりません。 ということです。
パッケージ内でスクリプトを実行することがアンチパターンであるかどうかは主観的なものですが、個人的には、いくつかのカスタムwxPythonウィジェットを含むパッケージでとても便利だと感じています。
wx.Frame
テスト用にそのウィジェットだけを含んでいます。
関連
-
風力制御におけるKS原理を深く理解するためのpythonアルゴリズム
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonで2つのリストを連結する方法は?
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み] 億の相対的輸入
-
[解決済み] Pythonで相対インポートを行うには?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Pythonに三項条件演算子はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ピロウズ画像色処理の具体的な活用方法
-
python string splicing.join()とsplitting.split()の説明
-
Python Pillow Image.save jpg画像圧縮問題
-
Python 入出力と高次代入の基礎知識
-
[解決済み] データ型が理解できない
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み] builtins.TypeError: strでなければならない、bytesではない
-
[解決済み】インポートエラー。モジュール名 urllib2 がない
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】ValueError: pickleプロトコルがサポートされていません。3、python2 pickleはpython3 pickleでダンプしたファイルを読み込むことができない?