1

このような方法で distutils を使用して Python でパッケージを作成しました。

#! /usr/bin/env python

from distutils.core import setup

setup(name='mypackage4.py',
    version='1.0',
    description='Description',
packages=['mypackage4']
)

setup.py はそれを私の python2.7/site-packages ディレクトリにインストールします。

私が走るとき

import mypackage4

mypackage4 ディレクトリにある .py ファイルを実行しようとします。このディレクトリには、関数 (def コマンド) を含む python ファイルが含まれています。私がやりたいのは、インポート時に直接実行するのではなく、関数を使用できるようにすることだけです。

しかし、私はそうします

cd python2.7/site-packages

次にインポートを実行して mypackage4 をローカルで取得し、何も実行せずにインポートするので、通常の方法で Python コマンド ラインから関数にアクセスできます。

パッケージがローカル ディレクトリにないときに python が関数を実行しているように見えるのに、パッケージがローカル ディレクトリにあるときに関数を実行しないのはなぜですか?

第二に、私は配置について読みました

if __name__ == '__main__':
    pass
else:
    <define functions here>

私の .py ファイルでコマンドを実行してそれらが実行されないようにしますが、確かに関数は実行されません。

どんな助けでも大歓迎です!

ps、(これが役立つ場合)私のパッケージディレクトリには、__init__.pyどのファイルをインポートするかをpythonに伝えるファイルがあります

__all__ = [
    'pyfile1',
    'pyfile2',
    'pyfile3',
]
4

1 に答える 1

3

このディレクトリには、関数 (def コマンド) を含む python ファイルが含まれています。私がやりたいのは、インポート時に直接実行するのではなく、関数を使用できるようにすることだけです。

ステートメントはコードであり、def実行する必要があります。そうしないと、関数が定義されません。モジュールまたはパッケージをインポートすると、Pythonは常にコードを実行します。関数、クラス、およびグローバル変数/定数の定義は、他のものと同様にコードです。

関数を呼び出すコードを記述しない限り、関数は呼び出されません。しかし、そのようなコードを書いた場合、それは実行されます。発生する特別な状態はありませんdef foo(i): print(i)が、発生foo(3)しません。すべてのコードが実行されます。

他のコードでインポートできるが、スクリプトとしても実行できるモジュールを作成したい場合があります。(または、モジュールがスクリプトとして実行されたときにテストを実行するようにすることもできます。) そこで__main__イディオムの出番です。

あなたはイディオムを少し間違っています。というか、典型的なケースの前に珍しいケースを置いています。通常、次のようにします。

def foo(f):
    blahblah(f)

def bar(fname):
    with open(fname) as f:
        foo(f)

if __name__ == '__main__':
    import sys
    for arg in sys.argv[1:]:
        bar(arg)

モジュールをインポートすると、fooとのbar定義が実行されるため、インポート コードは実行できますqux.bar(fname)が、ステートメント内のものはif実行されません (__name__ != '__main__'インポートされたモジュールのため)。モジュールをスクリプトとして実行すると、そのようなもの実行されます (なぜなら__name__ == '__main__')。だから、あなたは./qux.py myfile.txt(またはC:\Python33\Python.exe .\qux.py myfile.txt、または何でも)行うことができ、それはあなたのためにmyfile.txtから一体をfooします。

elseのブロックに何かを入れる必要はほとんどありませんif __name__ == '__main__'

しかし、決してそうではないことはめったにありません。モジュールをモジュールとして使用するためには必要であるが、スクリプトとして実行するためには必要ない定義がある場合があります。これらの定義のコンパイルに時間がかかる場合 (たとえば、モジュールがdict後でアクセスを高速化するために 100000 要素を事前計算するため)、スクリプトを実行するたびにコンパイルする必要はありません。したがって、これらの定義はelseブロックに入ります。

于 2013-01-07T07:35:06.943 に答える