質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

3550閲覧

【python3】packageの使い方について

shirai

総合スコア1290

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/07/07 07:06

編集2019/07/07 08:12

実現したいこと

このサイトを読んだのですが良く分からずです。

以下のようなツリー構造でプログラムを組んでいますが、
正しくmain.pyを実行するにはinit.pyにそれぞれどう記述するべきでしょうか。
また、ツリー構造は変更できないので、プログラム自体に間違いがあればそれも教えて頂きたいです。

ツリー構造

python

1# main.py 2from dirC import C 3 4main()

python

1# dirA/A.py 2import math 3 4class keisan(object): 5 def __init__(self, hankei): 6 self.hankei = hankei 7 def menseki(self): 8 return self.hankei * self.hankei * math.pi

python

1# dirA/dirB/B.py 2from .. import A 3 4class more_keisan(keisan): 5 def __init__(self, hankei): 6 super().__init__(hankei) 7 def ensyu(self): 8 return self.hankei * 2 * math.pi

python

1# dirC/C.py 2from ..dirA.dirB import B 3 4def main(): 5 inst = more_keisan(5) 6 7 print(inst.ensyu()) 8 print(inst.menseki())

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

__init__.py は関係ありません。
重要なのは、起動するスクリプトがいずれか、です。
仮に、「python3 main.py」と起動するならば、以下のようになります。

python

1# main.py 2from dirC.C import main 3 4main()

python

1# dirA/dirB/B.py 2from ..A import keisan 3 4class more_keisan(keisan): 5 pass

python

1# dirC/C.py 2from dirA.dirB.B import more_keisan 3 4def main(): 5 inst = more_keisan(5)

dirA/A.py」は、そのままです。


まず、三つの事を把握しなければなりません。

絶対importは、sys.pathに指定されたディレクトリ以下にあるモジュール/パッケージから指定しなければならない。

「絶対import」という言葉はマニュアルには出てこないのですが、説明しづらいので、ここでは「相対import」に対する対義語として使う事にします。

相対importは、同じルートパッケージのモジュール同士でしか指定できない。

「ルートパッケージ」という言葉もマニュアルに出てきませんが、これもないと説明がしづらいので、ここでは「sys.pathのディレクトリ直下にあるパッケージ(ディレクトリ)」という事にします。

起動時に、起動スクリプトのディレクトリがsys.pathの先頭に追加される。

マニュアルの以下のページに書かれています。

この事を踏まえて、先のスクリプトを見てみましょう。

python

1# dirC/C.py 2from dirA.dirB.B import more_keisan

main.py」から起動されたのであれば、sys.pathにmain.pyのあるディレクトリが追加されているはずなので、「dirA」「dirC」がルートパッケージになります。
dirA」と「dirC」とでは、ルートパッケージが違うので、「C.py」から「dirA」以下のモジュールを相対importすることはできないので、絶対importでインポートする必要があります。

python

1# dirA/dirB/B.py 2from ..A import keisan

dirA/A.py」と「dirA/dirB/B.py」は、同じ「dirA」をルートパッケージとするモジュールですので、相対importが使用できます。(絶対importも使用可能)


そもそも「ディレクトリ構成を変えない」というのが今回の条件でしたが、本当であれば、

main.py app/ dirA/ A.py DirB/ B.py dirC/C.py

というように、起動スクリプトの下にパッケージ(ディレクトリ)を作り、それ以外のスクリプトはそのパッケージ以下に配置し、お互いを相対importでインポートするのが好ましいと思います。

投稿2019/07/07 14:48

編集2019/07/07 14:50
katsuko

総合スコア3469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shirai

2019/07/07 15:36

とてもよく理解できました。 sys.pathについても検索してどのようなものか理解ができました。 困っていたのでとても助かりました。ありがとうございます。 ツリーの変更を上長に相談してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問