Python でモジュール内名前空間をつくる

やりたいこと

hoge.py の中で名前空間を実現したい。

動機

別ファイルを作ればモジュール化できるが、一ファイルで済ませたいから。

やり方

名前空間用の class を作り、(その名前空間に入れたい定義を)その中で定義する

コード

# coding: utf-8

class Namespace:

    class A:
        CONST = "A's const."

        def __init__(self, number):
            self._number = number

        @property
        def number(self):
            return self._number

        def __str__(self):
            return 'A::Number={}'.format(self._number)

        def clone_b(self):
            b = Namespace.B(self._number)
            return b

        def clone_c(self):
            c = Namespace.Namespace.C(self._number)
            return c
 
    class B:
        CONST = "B's const."

        def __init__(self, number):
            self._number = number

        @property
        def number(self):
            return self._number

        def __str__(self):
            return 'B::Number={}'.format(self._number)
 
    class Namespace:

        class C:
            CONST = "C's const."

            def __init__(self, number):
                self._number = number

            @property
            def number(self):
                return self._number

            def __str__(self):
                return 'C::Number={}'.format(self._number)

 
def p(obj):
    print(obj)

if __name__=='__main__':
    p(Namespace.A.CONST) # A's const.
    p(Namespace.B.CONST) # A's const.

    a1 = Namespace.A(100)
    p(a1) # A::Number=100

    b1 = Namespace.B(-100)
    p(b1) # B::Number=-100

    c1 = Namespace.Namespace.C(1048576)
    p(c1) # C::Number=1048576

    b2 = a1.clone_b()
    p(b2) # B::Number=100

    c2 = a1.clone_c()
    p(c2) # C::Number=100

実行結果

$ python namespace.py
A's const.
B's const.
A::Number=100
B::Number=-100
C::Number=1048576
B::Number=100
C::Number=100

その他ノウハウ

class の定義が二種類に分かれてしまい混乱するので、名前空間用クラスの名前を工夫する。

たとえば class util のように小文字で定義する。そうすると利用側でも util.xxxx の形で参照でき、モジュール利用時と同じ使い心地で違和感もない。