はじめに
pythonで自作パッケージをsetup.py
で作成する流れです。
意外とmodule not found
のエラーで手こずってしまったのでこちらに忘れないようにメモを残していきたいと思います。
今回はとくにPyPiなどにあげることはせず、単純にローカル環境でpip install
する手順を整理する感じです。
流れ
-
sample.py
、__init__.py
、setup.py
の内容を記述する -
pip install
してローカルにパッケージをインストール -
foo.py
の内容を記述して走らせる
ディレクトリの構造
以下の構造にて
-
sample.py
に入っている関数をpip install
でインストールして -
foo.py
でその関数たちを走らせるとします。
Documents
└ tasks_project
├ src
│ └ tasks
│ ├ __init__.py
│ └ sample.py # sample.pyにある関数をパッケージ化したい
├ hoge
│ └ foo.py # foo.pyでsample.pyの関数を走らせる
└ setup.py
この二つのディレクトリは従兄関係なので普通に相対インポートすると以下のようなエラーが出てしまいます。
attempted relative import beyond top-level package.
なので以下のようにしてpip でインストールしてどこからでもimportできるようにしていきます。
sample.py
、__init__.py
、setup.py
の内容を記述する
sample.py の内容
sample.py
では欲しい関数を書いていきます。シンプルに以下のようなものを書いてみました。
numpy
やpandas
がちゃんと使えるのか確認したかったのでいろんなモジュールをインポートしています。
import numpy as np
import pandas as pd
import datetime
def hello():
print("hello_world")
def get_array():
return np.array([1, 2, 3])
def get_df():
return pd.Series([1, 2, 3])
def get_date():
print(datetime.datetime(2019, 12, 1, 1, 1, 1))
__init__.py
の内容
ここを自分は書いていなかったため、module not found
エラーを吐かれていたのではないかと考えています。
ここでどの関数をpip install
の際にインストールするかの設定をする感じです。
from .sample import (
hello,
get_array,
get_df,
get_date,
)
__version__ = '0.1.0'
setup.py
の内容
setup.py
でpip install
する際の一番大事な設定を行います。
以下ではname
、version
、packages
、package_dir
ぐらいをちゃんと書いておけば大丈夫だと思います。
"""Minimal setup file for tasks project."""
from setuptools import setup, find_packages
setup(
name='tasks',
version='0.1.0',
license='proprietary',
description='Module Experiment',
author='greenteabiscuit',
author_email='hogehoge@gmail.com',
url='None.com',
packages=find_packages(where='src'),
package_dir={'': 'src'},
)
pip install
する
tasks_project
の一つ上のディレクトリ(今回の場合はDocuments
)に移動した上で、pip install
を行います。
$ cd Documents
$ pip install ./tasks_project/
Processing ./tasks_project
Building wheels for collected packages: tasks
Building wheel for tasks (setup.py) ... done
.......... 略 ..........
Successfully installed tasks-0.1.0
Successfuly installed
と出たら成功です。
foo.py
の内容を記述して走らせる
import tasks
tasks.hello()
arr = tasks.get_array()
print(arr)
df = tasks.get_df()
print(df)
tasks.get_date()
こちらを書いたら以下で走らせてエラーもなく結果が出されるはずです。
$ cd Documents/hoge/
$ python foo.py
hello_world
[1 2 3]
0 1
1 2
2 3
dtype: int64
2019-12-01 01:01:01
最後に
これでテストコードなどを書くのが少し楽になりそうです。
もっと早く知りたかったのですが、なぜかいい記事があまり見つからず。。。
以下の書籍の内容を参考にしています。
Python Testing with pytest: Simple, Rapid, Effective, and Scalable (English Edition)