Pythonモジュール/パッケージの書き方?


375

私は仕事で単純なタスク用のPythonスクリプトを作成しており、他の人が使用するためにそれらを実際にパッケージ化することを気にしていません。これで、REST APIのPythonラッパーを作成するよう割り当てられました。どのように始めればいいのか全くわからないので、助けが必要です。

私が持っているもの:

(できるだけ具体的にしたい)私はvirtualenvの準備ができています。これはgithubにもあります。Python用の.gitignoreファイルもそこにあります。さらに、REST APIと対話するためのリクエストライブラリもあります。それでおしまい。

これが現在のディレクトリツリーです

.
├── bin
   └── /the usual stuff/
├── include
   └── /the usual stuff/
├── lib
   └── python2.7
       └── /the usual stuff/
├── local
   └── /the usual stuff/
└── README.md

27 directories, 280 files

.pyファイルを作成する場合、どこに置くかさえわかりません。

私がやりたかったこと:

「pip install ...」でPythonモジュールをインストール可能にします

可能であれば、Pythonモジュールの記述に関する一般的な手順を追ったプロセスが必要です。


15
私はチュートリアルの第6章(2.7)から始めるか、ここで3.xを 検索します。インターネットでPythonモジュールチュートリアルを検索すると、他にもたくさん見つかります。
Roland Smith

6
誰もピップパートに答えなかった
whackamadoodle3000 2017

github.com/MacHu-GWU/pygitrepo-projectこのライブラリは、プロジェクトのスケルトンを最初から作成するのに役立ち、必要な機能はすぐに使用できます。
MacSanhe

回答:


424

モジュールは、Pythonの定義とステートメントを含むファイルです。ファイル名は、サフィックスが付いたモジュール名です。.py

作成しhello.py、次の関数をコンテンツとして記述します。

def helloworld():
   print "hello"

次に、インポートすることができますhello

>>> import hello
>>> hello.helloworld()
'hello'
>>>

多くの.pyファイルをグループ化するには、それらをフォルダーに入れます。を含むフォルダは、__init__.pyPythonではモジュールと見なされ、パッケージと呼ぶことができます

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

通常の方法で、モジュールのimportステートメントを使用できます。

詳細については、6.4を参照してくださいパッケージ


7
最後のものは次のようになります:HellowModuleからhellomoduleをインポートしますか?モジュールフォルダーでこんにちは、HelloModule import helloから
nycynik

現在Pythonで遊んでいて、この答えは私が遭遇した中で最も役立つものの1つでなければなりません。とてもよく説明してくれてありがとう。
ダレンウェインライト

「pip install」コマンドは機能しません。また、それを使用するには同じディレクトリにいる必要があります
Math Coder 101

234

Python 3-2015年11月18日更新

受け入れられた回答は有用であるとわかりましたが、自分の経験に基づいて他の人の利益のためにいくつかの点を拡張したいと考えました。

モジュール:モジュールは、Pythonの定義とステートメントを含むファイルです。ファイル名は、サフィックス.pyが追加されたモジュール名です。

モジュールの例:現在のディレクトリに単一のpythonスクリプトがあるとします。ここでは、mymodule.pyと呼んでいます。

ファイルmymodule.pyには、次のコードが含まれています。

def myfunc():
    print("Hello!")

現在のディレクトリからpython3インタープリターを実行する場合、関数myfuncをインポートして実行する方法は次のとおりです(通常、次のいずれかを選択します)。

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

OK、それで十分簡単でした。

ここで、現在の作業ディレクトリからアドホックで実行するだけでなく、モジュールの名前空間を提供するために、このモジュールを独自の専用フォルダーに配置する必要があると想定します。ここで、パッケージの概念を説明する価値があります

パッケージ:パッケージは、「ドット付きモジュール名」を使用してPythonのモジュール名前空間を構造化する方法です。たとえば、モジュール名ABは、Aというパッケージ内のBというサブモジュールを指定します。モジュールを使用すると、異なるモジュールの作成者が互いのグローバル変数名について心配する必要がなくなるのと同様に、ドット付きモジュール名を使用すると作成者が保存されますNumPyやPython Imaging Libraryなどのマルチモジュールパッケージを相互のモジュール名を気にする必要がないようにします。

パッケージの例:次のフォルダーとファイルがあるとします。ここで、mymodule.pyは前と同一であり、__init__.pyは空のファイルです。

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

__init__.pyファイルは、Pythonがディレクトリをパッケージを含むものとして扱うようにするために必要です。詳細については、後で提供されるモジュールのドキュメントリンクを参照してください。

現在の作業ディレクトリは、mypackageと呼ばれる通常のフォルダーの1つ上のレベルです。

$ ls
mypackage

ここでpython3インタープリターを実行すると、必要な関数myfuncを含むモジュールmymodule.pyをインポートして実行することができます(通常、次のいずれかを選択します)。

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

Pythonの3と仮定すると、で優れたドキュメントがあります:モジュール

パッケージとモジュールの命名規則に関しては、一般的なガイドラインはPEP-0008に記載されています- パッケージとモジュールの名前を参照してください

モジュールには、すべて小文字の短い名前を付ける必要があります。読みやすさが向上する場合は、モジュール名にアンダースコアを使用できます。Pythonパッケージも、すべて小文字の短い名前にする必要がありますが、アンダースコアの使用はお勧めしません。


5
素敵な簡単な説明。mypackage内に別のフォルダを保持したい場合はどうなりますか?
Anuj Gupta 2016

3
インクルードは、あなたが書いた内容に完全に依存します。モジュールの関数の外にものを置く場合、のように呼び出したときにそれを起動しますimport mypackage。モジュール(ファイルも含む)から関数のみをインポートする場合は、を使用することをお勧めしますfrom module import function。サブフォルダーをfrom subfolder.module import function使用すると、function()他のコード部分を起動せずに呼び出すことができます。また、from module import *本当に必要がない場合は使用しないでください。
m3nda 2016年

5
残っている唯一の質問は、パッケージにすべてをインポートする方法を教えてimport mypackageください。への追加import mymodule__init__.py機能しません..
576i

きちんとした説明!ただし、numpyがパッケージである場合、インタープリターでnumpy.cos(1)を実行するにはどうすればよいですか?番号?
user1935724 2017年

3
ピップはどうですか?
whackamadoodle3000 2017

199

このOPの質問はまだ誰も取り上げていないので、

私がやりたかったこと:

「pip install ...」でPythonモジュールをインストール可能にします

ここでは絶対的な最小限の例では、準備と使用は、PyPIにパッケージをアップロードする基本的な手順を示す、あるsetuptoolsとしtwine

これは、少なくともチュートリアルの代わりになるものではありません。この非常に基本的な例でカバーしている以上のことがたくさんあります。

パッケージの作成自体は、すでにここの他の回答でカバーされているので、そのステップがカバーされていて、プロジェクト構造が次のようになっていると仮定しましょう。

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

setuptoolsパッケージ化に使用するには、ファイルを追加する必要がありますsetup.py。これはプロジェクトのルートフォルダーに配置されます。

.
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

少なくとも、パッケージのメタデータを指定すると、次のsetup.pyようになります。

from setuptools import setup

setup(
    name='hellostackoverflow',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hellostackoverflow'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

を設定したので、reStructuredTextのreadmeファイルとともに、license='MIT'次のようにコピーをプロジェクトに含めLICENCE.txtますREADME.rst

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

この時点で、を使用してパッケージ化を開始する準備ができsetuptoolsています。まだインストールしていない場合は、次のコマンドでインストールできますpip

pip install setuptools

これを実行してを作成するsource distributionには、プロジェクトのルートフォルダーでsetup.py、コマンドラインからを呼び出して、次のように指定しますsdist

python setup.py sdist

これにより、配布パッケージとegg-infoが作成され、次のようなフォルダー構造になりますdist

.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

この時点で、を使用してインストールできるパッケージがあるpipので、プロジェクトルートから(この例のようにすべての名前が付けられていると仮定して):

pip install ./dist/hellostackoverflow-0.0.1.tar.gz

すべてがうまくいけば、Pythonインタープリターを開くことができます。混乱を避けるためにプロジェクトディレクトリの外のどこかで言い、光沢のある新しいパッケージを使用してみます。

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'

パッケージのインストールと動作を確認したので、PyPIにアップロードできます。

実験でライブリポジトリを汚染しないため、テストリポジトリ用のアカウントを作成twineし、アップロードプロセス用にインストールします。

pip install twine

アカウントが作成されtwine、パッケージをアップロードするように指示するだけで、資格情報を要求し、指定したリポジトリにパッケージをアップロードします。

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

これで、PyPIテストリポジトリのアカウントにログインして、しばらくの間、新しくアップロードしたパッケージに驚嘆し、次のコマンドを使用してそれを取得できpipます。

pip install --index-url https://test.pypi.org/simple/ hellostackoverflow

ご覧のとおり、基本的なプロセスはそれほど複雑ではありません。先に述べたように、ここで取り上げた以外にも多くのことがあるので、先に進んでチュートリアル読んでより詳細な説明を読んでください


パッケージはすぐに公開されsetuptoolsますか?
U10転送

@ U9-Forwardいいえ、公開はで行われtwineますが、で作成した後、公開する前にパッケージをローカルでテストできますsetuptools
bgse

9

選択したコマンドを定義したら、保存したファイルをPythonプログラムファイルのLibフォルダーにドラッグアンドドロップするだけです。

>>> import mymodule 
>>> mymodule.myfunc()

2

「hello.py」という名前のファイルを作成します

Python 2.xを使用している場合

def func():
    print "Hello"

Python 3.xを使用している場合

def func():
    print("Hello")

ファイルを実行します。次に、以下を試すことができます。

>>> import hello
>>> hello.func()
Hello

少し難しい場合は、以下を使用できます。

Python 2.xを使用している場合

def say(text):
    print text

Python 3.xを使用している場合

def say(text):
    print(text)

定義の横の括弧にあるものを参照してください?それは重要です。これは、定義内で使用できるものです。

テキスト-プログラムに必要なことを伝えたいときに使用できます。その名前によれば、それはテキストです。テキストの意味を知っていただければ幸いです。それは「単語」または「文」を意味します。

ファイルを実行します。次に、Python 3.xを使用している場合は、以下を試すことができます。

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

Python 2.xの場合-Python 3でも同じでしょうか?わからない Python 2.xを間違えた場合は修正してください(Python 2は知っていますが、Python 3を使用しています)


2

プロジェクトスケルトンを最初から簡単に開始できるようにプロジェクトを作成しましたhttps://github.com/MacHu-GWU/pygitrepo-project

また、テストプロジェクトを作成できますlearn_creating_py_package

次のようなさまざまな目的で必要なコンポーネントを学ぶことができます

  • virtualenvを作成する
  • 自分自身をインストールする
  • unittestを実行する
  • コードカバレッジを実行する
  • ドキュメントを作成する
  • ドキュメントを展開する
  • 別のPythonバージョンでunittestを実行する
  • PYPIにデプロイする

使用することの利点は、pygitrepoそれらの面倒が自動的に作成され、適応されていることですpackage_nameproject_namegithub_accountdocument host servicewindows or macos or linux

プロのようなpythonプロジェクトの開発を学ぶのに良い場所です。

これが役立つことを願っています。

ありがとうございました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.