環境システム株式会社公式HP

〒660-0083 兵庫県尼崎市道意町7-1-3
尼崎リサーチ・インキュベーションセンター512

アイコン06-6657-5130

アイコンsales@hydrolab.co.jp

お問い合わせ

アイコン06-6657-5130

アイコンsales@hydrolab.co.jp

お問い合わせ

蛇使いな彼女BLOG

【第128回】.pyファイルのパッケージ化について

2025.05.02

今日はタイトルの通り、Pythonプログラムが入ったフォルダのパッケージ化について説明していきます。

最近仕事の都合でこのような処理が必要になった事から、こちらに手順をまとめておこうと思いました。

用途はコマンドラインからプログラムの実行する場合や、譲渡を目的にしています。

ですので、ここで言うパッケージとは、アプリケーション的なグラフィカル操作は含みません。

【ディレクトリツリー】
C:.
│ mein.py
│ mein.pyproj

└─package
│ A.py
│ B.py
│ __init__.py

└─__pycache__
A.cpython-36.pyc
B.cpython-36.pyc
__init__.cpython-36.pyc

今回扱う構造は上で示すとおり。

mein.pyからpackageフォルダ直下のA.pyとB.pyをモジュールとして機能させるという仕様です。

サンプルコードは、ゲームでよくある確率ガチャを実装してみました😳

結果はレアリティと16種類のタイプの組み合わせで排出されます。

~/package/

from  . import A
from  . import B
import numpy as np


class Content():

    def __init__(self):
        self.distribution=["N", "HN", "R", "SR","UR"]
        self.probability=[0.5,0.3,0.14,0.05,0.01]

        self.elements=[
            "Fire","Water","Grass","Bug","Steel","Poison","Normal","Electric",
            "Rock","Ground","Flying","Fighting","Evil","Psychic","Dragon","Fairy"
            ]

    @property
    def prob(self):
        return self.probability

    @prob.setter
    def prob(self,prob):
        self.probability=prob

    def output_prob(self,size=1):
        Rarity=np.random.choice(self.distribution,size=size, p=self.probability)
        Type=np.random.choice(self.elements,size=size,)
        result=np.vstack((Rarity,Type))
        return result.T


import numpy as np
from . import A



class Bonus(A.Content):

    def __init__(self):
        super().__init__() 

        self.items={
            'up':[0.4,0.25,0.2,0.1,0.05],
            'down':[0.5,0.275,0.2,0.02,0.005],
            'none':[0.5,0.3,0.14,0.05,0.01],
            }


    def Get_item(self,):
        magnification=np.random.choice(['up','down','none'], p=[0.5,0.2,0.3])
        self.probability=self.items[magnification]
        return magnification

main.py

from package import A 
from package import B

# 通常確率で排出
print('Random character creation')
Con=A.Content()
print('Normal probability')
Con.prob
Con.output_prob(10)



# ボーナス確率で排出
print('Probability bonus')
Bon=B.Bonus()
print('結果:',Bon.Get_item())
Bon.prob
Bon.output_prob(10)

各Pythonスクリプトの役割については以下の通りで、

    • A.py:親クラス。主なレアリティとタイプを記載
    • B.py:子クラス。排出されるレアリティ確率を操作できる設定
    • main.py:A.pyとB.pyを呼び出して実行するスクリプト

となっています。

排出確率は(アルファベットの解釈が多数あるようですが)今回は

"N"(ノーマル)50%

 "HN"(ハイノーマル)30%

 "R"(レア)14%

 "SR"(スーパーレア)5%

"UR"(ウルトラレア)1%

これに対し16個のタイプが1/16の確率で組み合わさるものとしました。

main.pyを動かしてみると、

こんな感じで結果が出力されます。

この時、package側のインポート文の記述が通常と異なっているので簡単に説明すると、

通常、Pythonでは「import numpy as np」のようなimport (ライブラリ名) または from (ライブラリ名) import (モジュール名)といった絶対インポートを推奨していますが、これはメインプログラムに限ってであって、

package内のモジュール間でインポートを行う場合、importの前に「.」をつけることで相対インポートを行っています。このときの「.」は”現在のディレクトリ”を表しています。

そして、パッケージ化には__init__.pyの追加が必要だといわれますが、実はなくても普通に動きます。

大きなプロジェクトだと__init__.pyがあったほうが都合がいい場合もありますが、この程度のプログラムなら全く問題ないようです。

それでも__init__.pyを置く場合は、中身が空だろうが例のようにインポート文を書こうが、ご自由に。ということらしいです。(へぇ~)

結論としては、モジュールA・B、main.pyの冒頭インポートの記述を明示すれば、そのまま別のパソコンへ譲渡可能なんですね!ハイテクだ。(※プロジェクトの起動にはPython環境が必要)

そんなこんなで今回の話は終わりです

次回に続く。

pagetop