Pythonで、自分で定義したいくつかの関数をスクリプト(f.pyとします)にまとめて書いてあって、このスクリプトをモジュールとして読み込んで使いたいとします。

ここで、f.py内に書いた関数自体が色々な他のモジュールに依存している場合、そのモジュールの読み込みは、どこで行うのがいいのでしょうか。

1) f.pyのスクリプトの冒頭部分にモジュールのimportを書いておく。
2) 自分で定義する各関数内でimportを書く
3) f.pyではなくそれをインポートして実行する側のスクリプト(e.pyとします)にimportを書く

と3通りぐらいを考えました。

1)の場合、f.py内に定義した関数を呼び出して使う場合のみ(import済みとして)使用可能
2)の場合、その関数を呼び出す場合のみ使用可能
3)の場合、e.py内でf.pyに属する関数を呼び出した場合も使用可能

と理解しています。

関数定義を書く際に、依存するモジュールが外でインポートされてるか考えるのが面倒なので、関数定義内にimportを全部書いてしまいたいのですが、何か不都合が生じますでしょうか?

回答の条件
  • 1人10回まで
  • 13歳以上
  • 登録:2017/01/22 18:42:27
  • 終了:2017/01/26 23:55:27
id:midnightseminar

挙動の理解が正しいとすれば、その条件の下で書きたいように書けばいいだけかも知れませんが、ミスが少ないのはどういうやり方かとか、メリット・デメリットなどをアドバイスいただければと思います。

ベストアンサー

id:quintia No.1

quintia回答回数562ベストアンサー獲得回数712017/01/24 20:24:30

ポイント100pt

関数定義にimportを書くのは、モジュールが正常でない場合=importが失敗する場合に、そのエラーが発生するのが後になる、というデメリットがあるので、私はやらないし、基本的にするべきではないと思います。

import time

def a():
    import must_fail
    return

def b():
    # なんか時間がかかる処理のエミュレート
    time.sleep(30)
    return

if __name__ == '__main__':
    b()
    a()

を実行するとImportErrorが発生するのは30秒後です。
そのぐらいならまぁいいのですが、1時間ぐらい処理したあとに該当の関数が初めて呼ばれてエラーになったら目も当てられません。
失敗するときは最初に失敗するように書くべきでしょう。


PEP8の推奨もファイル先頭のdocstringのあと、モジュールグローバルな宣言の前であるべき、となっています。

id:midnightseminar

なるほど、ありがとう御座います。

2017/01/26 23:31:17

その他の回答(0件)

id:quintia No.1

quintia回答回数562ベストアンサー獲得回数712017/01/24 20:24:30ここでベストアンサー

ポイント100pt

関数定義にimportを書くのは、モジュールが正常でない場合=importが失敗する場合に、そのエラーが発生するのが後になる、というデメリットがあるので、私はやらないし、基本的にするべきではないと思います。

import time

def a():
    import must_fail
    return

def b():
    # なんか時間がかかる処理のエミュレート
    time.sleep(30)
    return

if __name__ == '__main__':
    b()
    a()

を実行するとImportErrorが発生するのは30秒後です。
そのぐらいならまぁいいのですが、1時間ぐらい処理したあとに該当の関数が初めて呼ばれてエラーになったら目も当てられません。
失敗するときは最初に失敗するように書くべきでしょう。


PEP8の推奨もファイル先頭のdocstringのあと、モジュールグローバルな宣言の前であるべき、となっています。

id:midnightseminar

なるほど、ありがとう御座います。

2017/01/26 23:31:17

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません