otsucfgmng


Nameotsucfgmng JSON
Version 1.3.3.311 PyPI version JSON
download
home_pagehttps://github.com/Otsuhachi/OtsuConfigurationManager.git
Summary設定ファイルを扱うクラスを生成するライブラリです。
upload_time2023-04-24 16:30:22
maintainer
docs_urlNone
authorOtsuhachi
requires_python>=3.11
licenseMIT License Copyright (c) 2021 Otsuhachi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords python configurationmanager configure json
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            - [概要](#概要)
  - [インストール](#インストール)
  - [使い方](#使い方)
  - [メソッド一覧](#メソッド一覧)
  - [Q\&A](#qa)


# 概要

このライブラリはjson形式の設定ファイルの読み書きを補助するための基底クラスです。  
`BaseCM`クラスを継承し、`__defaults__`, `<attributes>`を定義するだけで必要な操作を行えるようになります。  

~~現在~~違うセクションに同じキーを持つような設定ファイルには対応していません。  
**対応しないことに決定しました。**([理由はこちら](#なぜ異なるセクションで同名キーを持てないようにしましたか?))  

このライブラリは以下の環境で作成されています。
`Windows10(64bit)`, `Python3.11.1`

```python
# 違うセクションに同じキーを持つ例
{
    'app': {'name': 'Hello'},
    'default': {'name': 'Python'}
}
```

## インストール

インストール

`pip install otsucfgmng`

アップデート

`pip install -U otsucfgmng`

アンインストール

`pip uninstall otsucfgmng`

## 使い方

1. `otuvalidator`をインポートし、必要なバリデータ、コンバータを使用できるようにする
   - 自作クラスなどを使用したい場合には[OtsuValidator](https://github.com/Otsuhachi/OtsuValidator#%E7%B6%99%E6%89%BF%E8%A6%8F%E5%89%87)や実際のコードを参考に定義する([参考例](#自作クラスを使用する場合に必要なバリデータとコンバータをどう用意すればいいですか?))
1. `otsucfgmng`をインポートし、`BaseCM`を使用できるようにする
1. `BaseCM`を継承したクラスを定義する
   1. 属性`__defaults__`に辞書形式で利用する属性名とその初期値を与える
   1. `__hidden_options__`で隠しオプションを設定する (必要に応じて)
   1. `__defaults__`で宣言した属性名に1.で用意したコンバータを与える
1. 設定ファイルのパスを与えてインスタンスを作成する
1. インスタンスの属性を書き換えて編集を行う
1. `save_cm`を呼び出せば設定ファイルが出力される

<!-- omit in toc -->
### 実行例-設定ファイル管理クラス

<!-- no toc -->
- [作成](#作成-設定ファイル管理クラス)
- [読み込み](#読み込み-設定ファイル管理クラス)

<!-- omit in toc -->
### 作成-設定ファイル管理クラス


[実行例](#実行例-設定ファイル管理クラス)に戻る  

`cfg.json`という設定ファイルを作成していきます。

```python

# 1.
from otsuvalidator import CBool, CInt, CPath, CString

# 2.
from otsucfgmng import BaseCM


# 3.
class ConfigurationManager(BaseCM):
    # 3.1.
    __defaults__ = {
        'app': {
            'library': 'SampleLibrary.dll',
            'scripts': 'SampleScripts.scrpt',
            'title': 'Sample Program',
            'fullscreen': False
        },
        'audio': {
            'bgm': 100,
            'bgs': 100,
            'se': 100,
            'me': 85
        }
    }

    # 3.3.
    library = CPath('dll')
    scripts = CPath('scrpt')
    title = CString(1, checker=str.istitle)
    fullscreen = CBool()
    bgm = CInt(0, 100)
    bgs = CInt(0, 100)
    se = CInt(0, 100)
    me = CInt(0, 100)


# 4.
cm = ConfigurationManager('cfg.json')

# 5.
cm.bgm = 99
cm.bgs = 50

# 6.
cm.save_cm()
```

上記の処理で作成された`cfg.json`の中身は以下の通りです。  

```json

{
    "app": {},
    "audio": {
        "bgm": 99,
        "bgs": 50
    }
}
```

<!-- omit in toc -->
### 読み込み-設定ファイル管理クラス
[実行例](#実行例-設定ファイル管理クラス)に戻る  

正しい形式で出力された設定ファイルをインスタンスの生成時に与えると自動で設定を読み込みます。

```python

from otsuvalidator import CBool, CInt, CPath, CString

from otsucfgmng import BaseCM


class ConfigurationManager(BaseCM):
    __defaults__ = {
        'app': {
            'library': 'SampleLibrary.dll',
            'scripts': 'SampleScripts.scrpt',
            'title': 'Sample Program',
            'fullscreen': False
        },
        'audio': {
            'bgm': 100,
            'bgs': 100,
            'se': 100,
            'me': 85
        }
    }
    library = CPath('dll')
    scripts = CPath('scrpt')
    title = CString(1, checker=str.istitle)
    fullscreen = CBool()
    bgm = CInt(0, 100)
    bgs = CInt(0, 100)
    se = CInt(0, 100)
    me = CInt(0, 100)

# コンテキストマネージャを使用すると自動でsave_cmされます。
with ConfigurationManager('cfg.json') as cm:
    print(cm.user_cm())
    cm.fullscreen = 'yes'
    print(cm.user_cm())
```

```python
### 出力は以下のようになります ###
{'app': {}, 'audio': {'bgs': 50, 'bgm': 99}}
{'app': {'fullscreen': True}, 'audio': {'bgs': 50, 'bgm': 99}}
```


上記の処理で作成された`cfg.json`の中身は以下の通りです。  


```json

{
    "app": {
        "fullscreen": true
    },
    "audio": {
        "bgs": 50,
        "bgm": 99
    }
}
```

<!-- omit in toc -->
### 隠しオプション

[先ほどのコード](#読み込み-設定ファイル管理クラス)に隠しオプションを追加します。  
方法はシンプルで、`__hidden_options__`に対象の属性名のタプルを渡すだけです。  
今回は`fullscreen`と`me`属性を隠しオプションにしてみます。


```python

from otsuvalidator import CBool, CInt, CPath, CString

from otsucfgmng import BaseCM


class ConfigurationManager(BaseCM):
    __defaults__ = {
        'app': {
            'library': 'SampleLibrary.dll',
            'scripts': 'SampleScripts.scrpt',
            'title': 'Sample Program',
            'fullscreen': False
        },
        'audio': {
            'bgm': 100,
            'bgs': 100,
            'se': 100,
            'me': 85
        }
    }
    __hidden_options__ = ('fullscreen', 'me')  # この行を追加
    library = CPath('dll')
    scripts = CPath('scrpt')
    title = CString(1, checker=str.istitle)
    fullscreen = CBool()
    bgm = CInt(0, 100)
    bgs = CInt(0, 100)
    se = CInt(0, 100)
    me = CInt(0, 100)


with ConfigurationManager('cfg.json') as cm:
    print(cm.cfg_to_str_cm(True))

```

出力

```json

{
    "defaults": {
        "app": {
            "fullscreen": false,
            "library": "SampleLibrary.dll",
            "scripts": "SampleScripts.scrpt",
            "title": "Sample Program"
        },
        "audio": {
            "bgm": 100,
            "bgs": 100,
            "se": 100
        }
    },
    "user": {
        "app": {
            "fullscreen": true
        },
        "audio": {
            "bgm": 99,
            "bgs": 50
        }
    }
}
```

`cfg.json`は[ここ](#読み込み-設定ファイル管理クラス)で作成されたものが存在する前提になります。  
隠しオプションに設定した`me`は表示されていませんが、`fullscreen`は表示されていることがわかるかと思います。  
これは`fullscreen`が変更可能であることを知っている場合には隠す意味がないからです。


## メソッド一覧

`argparse`や`GUI`などで設定項目を編集するための補助を想定しています。  
`show`コマンドを作成して`cfg_to_str_cm`を制御するなど、自身のUIに合うように紐づけて使ってください。

名前|概要|戻り値|戻り値型
:--:|:--|:--:|:--:
cfg_to_str_cm|設定を`json.dumps`して返す<br>`all`を`True`にしている場合は標準設定も表示される<br>ユーザが変更していない`__hidden_options__`は表示されない<br>ユーザに設定を見せる場合にはこのメソッドを使って出力する|設定|str
load_cm|設定ファイルを読み込む<br>`__init__`から勝手に呼び出されるので、基本的に使用する必要はない||None
save_cm|現在の設定を書き出す<br>コンテキストマネージャを使用していれば勝手に呼び出される||None
reset_cm|各属性を初期値に戻す||None
defaults_cm|`__defaults__`のコピーを返す|初期設定|dict
user_cm|ユーザが変更した属性の辞書を返す|変更された設定|dict
key_place_cm|各属性がどのセクションに属するかを記録した辞書を返す<br>ユーザにアクセスを許すと`__hidden_options__`が意味をなくす|属性の所属先|dict
attributes_cm|設定項目の一覧を返す<br>ユーザにアクセスを許すと`__hidden_options__`が意味をなくす|設定項目の一覧|set



## Q&A

以下の説明で`cm`が登場した場合、ユーザが定義した設定ファイル管理クラスのインスタンスだと解釈してください。

- [なぜ異なるセクションで同名キーを持てないようにしましたか?](#なぜ異なるセクションで同名キーを持てないようにしましたか?)
- [自作クラスを使用する場合に必要なバリデータとコンバータをどう用意すればいいですか?](#自作クラスを使用する場合に必要なバリデータとコンバータをどう用意すればいいですか?)



<!-- omit in toc -->
### なぜ異なるセクションで同名キーを持てないようにしましたか?

1. 残念ながらライブラリ作成者の技術的な面も大きいです。
1. 後述する理由を克服、緩和する方法が追加、あるいは理解できれば異なるセクションでの同名キーを持てるようになる可能性も**なくはないです**。

ロガーの設定ファイルなど、異なるセクションで同名キーを持ちたい状況はありますが、それに対応する場合、アクセスが複雑になりすぎる恐れがあります。  

例えば、現在の属性へのアクセス`cm.<key>`に加えて、辞書を持つキーを`Section`クラスとして変換すれば`cm.<section>.<key>`, `cm.<sectionA>.<sectionB>.~.<key>`というように管理することは技術的に可能になります。

しかしそうなると、[実行例](#実行例)で使用したような構造の設定ではアクセスが煩雑になるデメリットもあります。  
`cm.fullscreen`でアクセスしていたものが`cm.app.fullscreen`となる等。  
また、動的にクラスを生成する都合上、コード入力支援が受けられず、ヒューマンエラーのリスクも上がってしまいます。

<!-- omit in toc -->
### 自作クラスを使用する場合に必要なバリデータとコンバータをどう用意すればいいですか?

1. `otsuvalidator.bases`から`Converter`, `Validator`をインポートし、使用できるようにする
   1. その他必要なライブラリをインポート
1. 自作クラスを定義する
   1. 好きなようにクラスを設計する (`__eq__`メソッドを定義していない場合`__hidden_options__`が正常に機能しない場合があります)
   1. `__str__`か`to_json`メソッドを定義する
1. 自作クラスに対応した`Validator`を定義する(以下そのValidatorを`VMyClass`とする)
1. `VMyClass`と`Converter`を継承した`CMyClass`を定義する
1. [使い方](#使い方)どおり


<!-- omit in toc -->
#### 実行例-自作クラスの使用

<!-- no toc -->
- [作成](#作成-自作クラスの使用)
- [読み込み](#読み込み-自作クラスの使用)


<!-- omit in toc -->
##### 作成-自作クラスの使用

[実行例](#実行例-自作クラスの使用)に戻る  

`my_company.json`という設定ファイルを作成していきます。  

`ConfigurationManager`では`json.dump`できない属性は`otsucfgmng.funcs.support_json_dump`関数で変換を試みます(※独自に指定しない限り)  
この関数では`to_json`を持つクラスを`cls.to_json`で、それ以外のクラスを`str(cls)`で変換します。  
なので、`cls.to_json`で返る値を`cls`に復元できるような`Converter`を定義すれば読み込み時に復元されます。

```python

# 1. & 1.1.
from typing import Any

from otsuvalidator import CNoneable
from otsuvalidator.bases import Converter, Validator

from otsucfgmng import BaseCM


# 2.
class Person:
    # 2.1.
    def __init__(self, name: str, age: int, gender: str):
        self.name = name
        self.age = age
        self.gender = gender

    def show_profile(self):
        print(self)

    # 2.2.
    def __str__(self) -> str:
        data = (
            ('名前', self.name),
            ('年齢', self.age),
            ('性', self.gender),
        )
        prof = []
        for k, v in data:
            prof.append(f'{k}\t: {v}')
        prof = '\n'.join(prof)
        return prof

    def to_json(self) -> dict:
        data = {'name': self.name, 'age': self.age, 'gender': self.gender}
        return data


# 3.
class VPerson(Validator):
    def validate(self, value: Any) -> Person:
        if type(value) is not Person:
            msg = self.ERRMSG('Person型である必要があります', value)
            raise TypeError(msg)
        return value


# 4.
class CPerson(VPerson, Converter):
    def validate(self, value: Any) -> Person:
        if type(value) is not Person:
            try:
                if isinstance(value, dict):
                    value = Person(**value)
                else:
                    raise TypeError
            except:
                msg = self.ERRMSG('Person型として扱える必要があります。', value)
                raise TypeError(msg)
        return super().validate(value)

    def super_validate(self, value: Any) -> Person:
        return super().super_validate(value)


# 5.
class ConfigurationManager(BaseCM):
    __defaults__ = {
        'president': Person('山田太郎', 28, '男'),
        'employee': {
            'director': Person('部長花子', 28, '女'),
            'manager': Person('課長夢', 28, '女'),
            'chief': Person('係長次郎', 28, '男')
        }
    }
    president = CPerson()
    director = CNoneable(CPerson())
    manager = CNoneable(CPerson())
    chief = CNoneable(CPerson())


with ConfigurationManager('my_company.json') as cm:
    cm.president = Person('乙八', 28, '男')
    cm.director = Person('部長夢', 28, '女')
    cm.manager = None
    cm.chief = None
```

上記の処理で作成された`my_company.json`の中身は以下の通りです。  


```json

{
    "employee": {
        "chief": null,
        "manager": null,
        "director": {
            "name": "部長夢",
            "age": 28,
            "gender": "女"
        }
    },
    "president": {
        "name": "乙八",
        "age": 28,
        "gender": "男"
    }
}
```

定義通り`Person`クラスは`person.to_json`を通して辞書形式に変換されていることがわかります。

<!-- omit in toc -->
##### 読み込み-自作クラスの使用

[実行例](#実行例-自作クラスの使用)に戻る  

```python

# 1. & 1.1.
from typing import Any

from otsuvalidator import CNoneable
from otsuvalidator.bases import Converter, Validator

from otsucfgmng import BaseCM


# 2.
class Person:
    # 2.1.
    def __init__(self, name: str, age: int, gender: str):
        self.name = name
        self.age = age
        self.gender = gender

    def show_profile(self):
        print(self)

    # 2.2.
    def __str__(self) -> str:
        data = (
            ('名前', self.name),
            ('年齢', self.age),
            ('性', self.gender),
        )
        prof = []
        for k, v in data:
            prof.append(f'{k}\t: {v}')
        prof = '\n'.join(prof)
        return prof

    def to_json(self) -> dict:
        data = {'name': self.name, 'age': self.age, 'gender': self.gender}
        return data


# 3.
class VPerson(Validator):
    def validate(self, value: Any) -> Person:
        if type(value) is not Person:
            msg = self.ERRMSG('Person型である必要があります', value)
            raise TypeError(msg)
        return value


# 4.
class CPerson(VPerson, Converter):
    def validate(self, value: Any) -> Person:
        if type(value) is not Person:
            try:
                if isinstance(value, dict):
                    value = Person(**value)
                else:
                    raise TypeError
            except:
                msg = self.ERRMSG('Person型として扱える必要があります。', value)
                raise TypeError(msg)
        return super().validate(value)

    def super_validate(self, value: Any) -> Person:
        return super().super_validate(value)


# 5.
class ConfigurationManager(BaseCM):
    __defaults__ = {
        'president': Person('山田太郎', 28, '男'),
        'employee': {
            'director': Person('部長花子', 28, '女'),
            'manager': Person('課長夢', 28, '女'),
            'chief': Person('係長次郎', 28, '男')
        }
    }
    president = CPerson()
    director = CNoneable(CPerson())
    manager = CNoneable(CPerson())
    chief = CNoneable(CPerson())


with ConfigurationManager('my_company.json') as cm:
    for i, key in enumerate(('president', 'director', 'manager', 'chief')):
        if i:
            print('-' * 75)
        print(f'{key}\n{getattr(cm,key)}')

```

```console

### 出力は以下のようになります ###
president
名前    : 乙八
年齢    : 28
性      : 男
---------------------------------------------------------------------------
director
名前    : 部長夢
年齢    : 28
性      : 女
---------------------------------------------------------------------------
manager
None
---------------------------------------------------------------------------
chief
None
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Otsuhachi/OtsuConfigurationManager.git",
    "name": "otsucfgmng",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "",
    "keywords": "Python ConfigurationManager Configure json",
    "author": "Otsuhachi",
    "author_email": "agequodagis.tufuiegoeris@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/b8/15/3569debdeef8a6496b721853a5647975c8937f7143521d401706bd5e87cc/otsucfgmng-1.3.3.311.tar.gz",
    "platform": null,
    "description": "- [\u6982\u8981](#\u6982\u8981)\r\n  - [\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb](#\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb)\r\n  - [\u4f7f\u3044\u65b9](#\u4f7f\u3044\u65b9)\r\n  - [\u30e1\u30bd\u30c3\u30c9\u4e00\u89a7](#\u30e1\u30bd\u30c3\u30c9\u4e00\u89a7)\r\n  - [Q\\&A](#qa)\r\n\r\n\r\n# \u6982\u8981\r\n\r\n\u3053\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u306fjson\u5f62\u5f0f\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u8aad\u307f\u66f8\u304d\u3092\u88dc\u52a9\u3059\u308b\u305f\u3081\u306e\u57fa\u5e95\u30af\u30e9\u30b9\u3067\u3059\u3002  \r\n`BaseCM`\u30af\u30e9\u30b9\u3092\u7d99\u627f\u3057\u3001`__defaults__`, `<attributes>`\u3092\u5b9a\u7fa9\u3059\u308b\u3060\u3051\u3067\u5fc5\u8981\u306a\u64cd\u4f5c\u3092\u884c\u3048\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002  \r\n\r\n~~\u73fe\u5728~~\u9055\u3046\u30bb\u30af\u30b7\u30e7\u30f3\u306b\u540c\u3058\u30ad\u30fc\u3092\u6301\u3064\u3088\u3046\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u306f\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u305b\u3093\u3002  \r\n**\u5bfe\u5fdc\u3057\u306a\u3044\u3053\u3068\u306b\u6c7a\u5b9a\u3057\u307e\u3057\u305f\u3002**([\u7406\u7531\u306f\u3053\u3061\u3089](#\u306a\u305c\u7570\u306a\u308b\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u540c\u540d\u30ad\u30fc\u3092\u6301\u3066\u306a\u3044\u3088\u3046\u306b\u3057\u307e\u3057\u305f\u304b\uff1f))  \r\n\r\n\u3053\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u306f\u4ee5\u4e0b\u306e\u74b0\u5883\u3067\u4f5c\u6210\u3055\u308c\u3066\u3044\u307e\u3059\u3002\r\n`Windows10(64bit)`, `Python3.11.1`\r\n\r\n```python\r\n# \u9055\u3046\u30bb\u30af\u30b7\u30e7\u30f3\u306b\u540c\u3058\u30ad\u30fc\u3092\u6301\u3064\u4f8b\r\n{\r\n    'app': {'name': 'Hello'},\r\n    'default': {'name': 'Python'}\r\n}\r\n```\r\n\r\n## \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n\r\n\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n\r\n`pip install otsucfgmng`\r\n\r\n\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\r\n\r\n`pip install -U otsucfgmng`\r\n\r\n\u30a2\u30f3\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n\r\n`pip uninstall otsucfgmng`\r\n\r\n## \u4f7f\u3044\u65b9\r\n\r\n1. `otuvalidator`\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\u3057\u3001\u5fc5\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30bf\u3001\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\r\n   - \u81ea\u4f5c\u30af\u30e9\u30b9\u306a\u3069\u3092\u4f7f\u7528\u3057\u305f\u3044\u5834\u5408\u306b\u306f[OtsuValidator](https://github.com/Otsuhachi/OtsuValidator#%E7%B6%99%E6%89%BF%E8%A6%8F%E5%89%87)\u3084\u5b9f\u969b\u306e\u30b3\u30fc\u30c9\u3092\u53c2\u8003\u306b\u5b9a\u7fa9\u3059\u308b([\u53c2\u8003\u4f8b](#\u81ea\u4f5c\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u5fc5\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30bf\u3068\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u3069\u3046\u7528\u610f\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f))\r\n1. `otsucfgmng`\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\u3057\u3001`BaseCM`\u3092\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\r\n1. `BaseCM`\u3092\u7d99\u627f\u3057\u305f\u30af\u30e9\u30b9\u3092\u5b9a\u7fa9\u3059\u308b\r\n   1. \u5c5e\u6027`__defaults__`\u306b\u8f9e\u66f8\u5f62\u5f0f\u3067\u5229\u7528\u3059\u308b\u5c5e\u6027\u540d\u3068\u305d\u306e\u521d\u671f\u5024\u3092\u4e0e\u3048\u308b\r\n   1. `__hidden_options__`\u3067\u96a0\u3057\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8a2d\u5b9a\u3059\u308b (\u5fc5\u8981\u306b\u5fdc\u3058\u3066)\r\n   1. `__defaults__`\u3067\u5ba3\u8a00\u3057\u305f\u5c5e\u6027\u540d\u306b1.\u3067\u7528\u610f\u3057\u305f\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u4e0e\u3048\u308b\r\n1. \u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u30d1\u30b9\u3092\u4e0e\u3048\u3066\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\u3059\u308b\r\n1. \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5c5e\u6027\u3092\u66f8\u304d\u63db\u3048\u3066\u7de8\u96c6\u3092\u884c\u3046\r\n1. `save_cm`\u3092\u547c\u3073\u51fa\u305b\u3070\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u304c\u51fa\u529b\u3055\u308c\u308b\r\n\r\n<!-- omit in toc -->\r\n### \u5b9f\u884c\u4f8b-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9\r\n\r\n<!-- no toc -->\r\n- [\u4f5c\u6210](#\u4f5c\u6210-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9)\r\n- [\u8aad\u307f\u8fbc\u307f](#\u8aad\u307f\u8fbc\u307f-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9)\r\n\r\n<!-- omit in toc -->\r\n### \u4f5c\u6210-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9\r\n\r\n\r\n[\u5b9f\u884c\u4f8b](#\u5b9f\u884c\u4f8b-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9)\u306b\u623b\u308b  \r\n\r\n`cfg.json`\u3068\u3044\u3046\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u3066\u3044\u304d\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# 1.\r\nfrom otsuvalidator import CBool, CInt, CPath, CString\r\n\r\n# 2.\r\nfrom otsucfgmng import BaseCM\r\n\r\n\r\n# 3.\r\nclass ConfigurationManager(BaseCM):\r\n    # 3.1.\r\n    __defaults__ = {\r\n        'app': {\r\n            'library': 'SampleLibrary.dll',\r\n            'scripts': 'SampleScripts.scrpt',\r\n            'title': 'Sample Program',\r\n            'fullscreen': False\r\n        },\r\n        'audio': {\r\n            'bgm': 100,\r\n            'bgs': 100,\r\n            'se': 100,\r\n            'me': 85\r\n        }\r\n    }\r\n\r\n    # 3.3.\r\n    library = CPath('dll')\r\n    scripts = CPath('scrpt')\r\n    title = CString(1, checker=str.istitle)\r\n    fullscreen = CBool()\r\n    bgm = CInt(0, 100)\r\n    bgs = CInt(0, 100)\r\n    se = CInt(0, 100)\r\n    me = CInt(0, 100)\r\n\r\n\r\n# 4.\r\ncm = ConfigurationManager('cfg.json')\r\n\r\n# 5.\r\ncm.bgm = 99\r\ncm.bgs = 50\r\n\r\n# 6.\r\ncm.save_cm()\r\n```\r\n\r\n\u4e0a\u8a18\u306e\u51e6\u7406\u3067\u4f5c\u6210\u3055\u308c\u305f`cfg.json`\u306e\u4e2d\u8eab\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002  \r\n\r\n```json\r\n\r\n{\r\n    \"app\": {},\r\n    \"audio\": {\r\n        \"bgm\": 99,\r\n        \"bgs\": 50\r\n    }\r\n}\r\n```\r\n\r\n<!-- omit in toc -->\r\n### \u8aad\u307f\u8fbc\u307f-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9\r\n[\u5b9f\u884c\u4f8b](#\u5b9f\u884c\u4f8b-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9)\u306b\u623b\u308b  \r\n\r\n\u6b63\u3057\u3044\u5f62\u5f0f\u3067\u51fa\u529b\u3055\u308c\u305f\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u751f\u6210\u6642\u306b\u4e0e\u3048\u308b\u3068\u81ea\u52d5\u3067\u8a2d\u5b9a\u3092\u8aad\u307f\u8fbc\u307f\u307e\u3059\u3002\r\n\r\n```python\r\n\r\nfrom otsuvalidator import CBool, CInt, CPath, CString\r\n\r\nfrom otsucfgmng import BaseCM\r\n\r\n\r\nclass ConfigurationManager(BaseCM):\r\n    __defaults__ = {\r\n        'app': {\r\n            'library': 'SampleLibrary.dll',\r\n            'scripts': 'SampleScripts.scrpt',\r\n            'title': 'Sample Program',\r\n            'fullscreen': False\r\n        },\r\n        'audio': {\r\n            'bgm': 100,\r\n            'bgs': 100,\r\n            'se': 100,\r\n            'me': 85\r\n        }\r\n    }\r\n    library = CPath('dll')\r\n    scripts = CPath('scrpt')\r\n    title = CString(1, checker=str.istitle)\r\n    fullscreen = CBool()\r\n    bgm = CInt(0, 100)\r\n    bgs = CInt(0, 100)\r\n    se = CInt(0, 100)\r\n    me = CInt(0, 100)\r\n\r\n# \u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30de\u30cd\u30fc\u30b8\u30e3\u3092\u4f7f\u7528\u3059\u308b\u3068\u81ea\u52d5\u3067save_cm\u3055\u308c\u307e\u3059\u3002\r\nwith ConfigurationManager('cfg.json') as cm:\r\n    print(cm.user_cm())\r\n    cm.fullscreen = 'yes'\r\n    print(cm.user_cm())\r\n```\r\n\r\n```python\r\n### \u51fa\u529b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059 ###\r\n{'app': {}, 'audio': {'bgs': 50, 'bgm': 99}}\r\n{'app': {'fullscreen': True}, 'audio': {'bgs': 50, 'bgm': 99}}\r\n```\r\n\r\n\r\n\u4e0a\u8a18\u306e\u51e6\u7406\u3067\u4f5c\u6210\u3055\u308c\u305f`cfg.json`\u306e\u4e2d\u8eab\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002  \r\n\r\n\r\n```json\r\n\r\n{\r\n    \"app\": {\r\n        \"fullscreen\": true\r\n    },\r\n    \"audio\": {\r\n        \"bgs\": 50,\r\n        \"bgm\": 99\r\n    }\r\n}\r\n```\r\n\r\n<!-- omit in toc -->\r\n### \u96a0\u3057\u30aa\u30d7\u30b7\u30e7\u30f3\r\n\r\n[\u5148\u307b\u3069\u306e\u30b3\u30fc\u30c9](#\u8aad\u307f\u8fbc\u307f-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9)\u306b\u96a0\u3057\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002  \r\n\u65b9\u6cd5\u306f\u30b7\u30f3\u30d7\u30eb\u3067\u3001`__hidden_options__`\u306b\u5bfe\u8c61\u306e\u5c5e\u6027\u540d\u306e\u30bf\u30d7\u30eb\u3092\u6e21\u3059\u3060\u3051\u3067\u3059\u3002  \r\n\u4eca\u56de\u306f`fullscreen`\u3068`me`\u5c5e\u6027\u3092\u96a0\u3057\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3057\u3066\u307f\u307e\u3059\u3002\r\n\r\n\r\n```python\r\n\r\nfrom otsuvalidator import CBool, CInt, CPath, CString\r\n\r\nfrom otsucfgmng import BaseCM\r\n\r\n\r\nclass ConfigurationManager(BaseCM):\r\n    __defaults__ = {\r\n        'app': {\r\n            'library': 'SampleLibrary.dll',\r\n            'scripts': 'SampleScripts.scrpt',\r\n            'title': 'Sample Program',\r\n            'fullscreen': False\r\n        },\r\n        'audio': {\r\n            'bgm': 100,\r\n            'bgs': 100,\r\n            'se': 100,\r\n            'me': 85\r\n        }\r\n    }\r\n    __hidden_options__ = ('fullscreen', 'me')  # \u3053\u306e\u884c\u3092\u8ffd\u52a0\r\n    library = CPath('dll')\r\n    scripts = CPath('scrpt')\r\n    title = CString(1, checker=str.istitle)\r\n    fullscreen = CBool()\r\n    bgm = CInt(0, 100)\r\n    bgs = CInt(0, 100)\r\n    se = CInt(0, 100)\r\n    me = CInt(0, 100)\r\n\r\n\r\nwith ConfigurationManager('cfg.json') as cm:\r\n    print(cm.cfg_to_str_cm(True))\r\n\r\n```\r\n\r\n\u51fa\u529b\r\n\r\n```json\r\n\r\n{\r\n    \"defaults\": {\r\n        \"app\": {\r\n            \"fullscreen\": false,\r\n            \"library\": \"SampleLibrary.dll\",\r\n            \"scripts\": \"SampleScripts.scrpt\",\r\n            \"title\": \"Sample Program\"\r\n        },\r\n        \"audio\": {\r\n            \"bgm\": 100,\r\n            \"bgs\": 100,\r\n            \"se\": 100\r\n        }\r\n    },\r\n    \"user\": {\r\n        \"app\": {\r\n            \"fullscreen\": true\r\n        },\r\n        \"audio\": {\r\n            \"bgm\": 99,\r\n            \"bgs\": 50\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n`cfg.json`\u306f[\u3053\u3053](#\u8aad\u307f\u8fbc\u307f-\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9)\u3067\u4f5c\u6210\u3055\u308c\u305f\u3082\u306e\u304c\u5b58\u5728\u3059\u308b\u524d\u63d0\u306b\u306a\u308a\u307e\u3059\u3002  \r\n\u96a0\u3057\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u8a2d\u5b9a\u3057\u305f`me`\u306f\u8868\u793a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u304c\u3001`fullscreen`\u306f\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u304c\u308f\u304b\u308b\u304b\u3068\u601d\u3044\u307e\u3059\u3002  \r\n\u3053\u308c\u306f`fullscreen`\u304c\u5909\u66f4\u53ef\u80fd\u3067\u3042\u308b\u3053\u3068\u3092\u77e5\u3063\u3066\u3044\u308b\u5834\u5408\u306b\u306f\u96a0\u3059\u610f\u5473\u304c\u306a\u3044\u304b\u3089\u3067\u3059\u3002\r\n\r\n\r\n## \u30e1\u30bd\u30c3\u30c9\u4e00\u89a7\r\n\r\n`argparse`\u3084`GUI`\u306a\u3069\u3067\u8a2d\u5b9a\u9805\u76ee\u3092\u7de8\u96c6\u3059\u308b\u305f\u3081\u306e\u88dc\u52a9\u3092\u60f3\u5b9a\u3057\u3066\u3044\u307e\u3059\u3002  \r\n`show`\u30b3\u30de\u30f3\u30c9\u3092\u4f5c\u6210\u3057\u3066`cfg_to_str_cm`\u3092\u5236\u5fa1\u3059\u308b\u306a\u3069\u3001\u81ea\u8eab\u306eUI\u306b\u5408\u3046\u3088\u3046\u306b\u7d10\u3065\u3051\u3066\u4f7f\u3063\u3066\u304f\u3060\u3055\u3044\u3002\r\n\r\n\u540d\u524d|\u6982\u8981|\u623b\u308a\u5024|\u623b\u308a\u5024\u578b\r\n:--:|:--|:--:|:--:\r\ncfg_to_str_cm|\u8a2d\u5b9a\u3092`json.dumps`\u3057\u3066\u8fd4\u3059<br>`all`\u3092`True`\u306b\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u6a19\u6e96\u8a2d\u5b9a\u3082\u8868\u793a\u3055\u308c\u308b<br>\u30e6\u30fc\u30b6\u304c\u5909\u66f4\u3057\u3066\u3044\u306a\u3044`__hidden_options__`\u306f\u8868\u793a\u3055\u308c\u306a\u3044<br>\u30e6\u30fc\u30b6\u306b\u8a2d\u5b9a\u3092\u898b\u305b\u308b\u5834\u5408\u306b\u306f\u3053\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u3063\u3066\u51fa\u529b\u3059\u308b|\u8a2d\u5b9a|str\r\nload_cm|\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3080<br>`__init__`\u304b\u3089\u52dd\u624b\u306b\u547c\u3073\u51fa\u3055\u308c\u308b\u306e\u3067\u3001\u57fa\u672c\u7684\u306b\u4f7f\u7528\u3059\u308b\u5fc5\u8981\u306f\u306a\u3044||None\r\nsave_cm|\u73fe\u5728\u306e\u8a2d\u5b9a\u3092\u66f8\u304d\u51fa\u3059<br>\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30de\u30cd\u30fc\u30b8\u30e3\u3092\u4f7f\u7528\u3057\u3066\u3044\u308c\u3070\u52dd\u624b\u306b\u547c\u3073\u51fa\u3055\u308c\u308b||None\r\nreset_cm|\u5404\u5c5e\u6027\u3092\u521d\u671f\u5024\u306b\u623b\u3059||None\r\ndefaults_cm|`__defaults__`\u306e\u30b3\u30d4\u30fc\u3092\u8fd4\u3059|\u521d\u671f\u8a2d\u5b9a|dict\r\nuser_cm|\u30e6\u30fc\u30b6\u304c\u5909\u66f4\u3057\u305f\u5c5e\u6027\u306e\u8f9e\u66f8\u3092\u8fd4\u3059|\u5909\u66f4\u3055\u308c\u305f\u8a2d\u5b9a|dict\r\nkey_place_cm|\u5404\u5c5e\u6027\u304c\u3069\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u306b\u5c5e\u3059\u308b\u304b\u3092\u8a18\u9332\u3057\u305f\u8f9e\u66f8\u3092\u8fd4\u3059<br>\u30e6\u30fc\u30b6\u306b\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u3059\u3068`__hidden_options__`\u304c\u610f\u5473\u3092\u306a\u304f\u3059|\u5c5e\u6027\u306e\u6240\u5c5e\u5148|dict\r\nattributes_cm|\u8a2d\u5b9a\u9805\u76ee\u306e\u4e00\u89a7\u3092\u8fd4\u3059<br>\u30e6\u30fc\u30b6\u306b\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u3059\u3068`__hidden_options__`\u304c\u610f\u5473\u3092\u306a\u304f\u3059|\u8a2d\u5b9a\u9805\u76ee\u306e\u4e00\u89a7|set\r\n\r\n\r\n\r\n## Q&A\r\n\r\n\u4ee5\u4e0b\u306e\u8aac\u660e\u3067`cm`\u304c\u767b\u5834\u3057\u305f\u5834\u5408\u3001\u30e6\u30fc\u30b6\u304c\u5b9a\u7fa9\u3057\u305f\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u30af\u30e9\u30b9\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3060\u3068\u89e3\u91c8\u3057\u3066\u304f\u3060\u3055\u3044\u3002\r\n\r\n- [\u306a\u305c\u7570\u306a\u308b\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u540c\u540d\u30ad\u30fc\u3092\u6301\u3066\u306a\u3044\u3088\u3046\u306b\u3057\u307e\u3057\u305f\u304b\uff1f](#\u306a\u305c\u7570\u306a\u308b\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u540c\u540d\u30ad\u30fc\u3092\u6301\u3066\u306a\u3044\u3088\u3046\u306b\u3057\u307e\u3057\u305f\u304b\uff1f)\r\n- [\u81ea\u4f5c\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u5fc5\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30bf\u3068\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u3069\u3046\u7528\u610f\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f](#\u81ea\u4f5c\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u5fc5\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30bf\u3068\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u3069\u3046\u7528\u610f\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f)\r\n\r\n\r\n\r\n<!-- omit in toc -->\r\n### \u306a\u305c\u7570\u306a\u308b\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u540c\u540d\u30ad\u30fc\u3092\u6301\u3066\u306a\u3044\u3088\u3046\u306b\u3057\u307e\u3057\u305f\u304b\uff1f\r\n\r\n1. \u6b8b\u5ff5\u306a\u304c\u3089\u30e9\u30a4\u30d6\u30e9\u30ea\u4f5c\u6210\u8005\u306e\u6280\u8853\u7684\u306a\u9762\u3082\u5927\u304d\u3044\u3067\u3059\u3002\r\n1. \u5f8c\u8ff0\u3059\u308b\u7406\u7531\u3092\u514b\u670d\u3001\u7de9\u548c\u3059\u308b\u65b9\u6cd5\u304c\u8ffd\u52a0\u3001\u3042\u308b\u3044\u306f\u7406\u89e3\u3067\u304d\u308c\u3070\u7570\u306a\u308b\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306e\u540c\u540d\u30ad\u30fc\u3092\u6301\u3066\u308b\u3088\u3046\u306b\u306a\u308b\u53ef\u80fd\u6027\u3082**\u306a\u304f\u306f\u306a\u3044\u3067\u3059**\u3002\r\n\r\n\u30ed\u30ac\u30fc\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306a\u3069\u3001\u7570\u306a\u308b\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u540c\u540d\u30ad\u30fc\u3092\u6301\u3061\u305f\u3044\u72b6\u6cc1\u306f\u3042\u308a\u307e\u3059\u304c\u3001\u305d\u308c\u306b\u5bfe\u5fdc\u3059\u308b\u5834\u5408\u3001\u30a2\u30af\u30bb\u30b9\u304c\u8907\u96d1\u306b\u306a\u308a\u3059\u304e\u308b\u6050\u308c\u304c\u3042\u308a\u307e\u3059\u3002  \r\n\r\n\u4f8b\u3048\u3070\u3001\u73fe\u5728\u306e\u5c5e\u6027\u3078\u306e\u30a2\u30af\u30bb\u30b9`cm.<key>`\u306b\u52a0\u3048\u3066\u3001\u8f9e\u66f8\u3092\u6301\u3064\u30ad\u30fc\u3092`Section`\u30af\u30e9\u30b9\u3068\u3057\u3066\u5909\u63db\u3059\u308c\u3070`cm.<section>.<key>`, `cm.<sectionA>.<sectionB>.~.<key>`\u3068\u3044\u3046\u3088\u3046\u306b\u7ba1\u7406\u3059\u308b\u3053\u3068\u306f\u6280\u8853\u7684\u306b\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\r\n\r\n\u3057\u304b\u3057\u305d\u3046\u306a\u308b\u3068\u3001[\u5b9f\u884c\u4f8b](#\u5b9f\u884c\u4f8b)\u3067\u4f7f\u7528\u3057\u305f\u3088\u3046\u306a\u69cb\u9020\u306e\u8a2d\u5b9a\u3067\u306f\u30a2\u30af\u30bb\u30b9\u304c\u7169\u96d1\u306b\u306a\u308b\u30c7\u30e1\u30ea\u30c3\u30c8\u3082\u3042\u308a\u307e\u3059\u3002  \r\n`cm.fullscreen`\u3067\u30a2\u30af\u30bb\u30b9\u3057\u3066\u3044\u305f\u3082\u306e\u304c`cm.app.fullscreen`\u3068\u306a\u308b\u7b49\u3002  \r\n\u307e\u305f\u3001\u52d5\u7684\u306b\u30af\u30e9\u30b9\u3092\u751f\u6210\u3059\u308b\u90fd\u5408\u4e0a\u3001\u30b3\u30fc\u30c9\u5165\u529b\u652f\u63f4\u304c\u53d7\u3051\u3089\u308c\u305a\u3001\u30d2\u30e5\u30fc\u30de\u30f3\u30a8\u30e9\u30fc\u306e\u30ea\u30b9\u30af\u3082\u4e0a\u304c\u3063\u3066\u3057\u307e\u3044\u307e\u3059\u3002\r\n\r\n<!-- omit in toc -->\r\n### \u81ea\u4f5c\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u5fc5\u8981\u306a\u30d0\u30ea\u30c7\u30fc\u30bf\u3068\u30b3\u30f3\u30d0\u30fc\u30bf\u3092\u3069\u3046\u7528\u610f\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f\r\n\r\n1. `otsuvalidator.bases`\u304b\u3089`Converter`, `Validator`\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\u3057\u3001\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\r\n   1. \u305d\u306e\u4ed6\u5fc5\u8981\u306a\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\r\n1. \u81ea\u4f5c\u30af\u30e9\u30b9\u3092\u5b9a\u7fa9\u3059\u308b\r\n   1. \u597d\u304d\u306a\u3088\u3046\u306b\u30af\u30e9\u30b9\u3092\u8a2d\u8a08\u3059\u308b (`__eq__`\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3057\u3066\u3044\u306a\u3044\u5834\u5408`__hidden_options__`\u304c\u6b63\u5e38\u306b\u6a5f\u80fd\u3057\u306a\u3044\u5834\u5408\u304c\u3042\u308a\u307e\u3059)\r\n   1. `__str__`\u304b`to_json`\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3059\u308b\r\n1. \u81ea\u4f5c\u30af\u30e9\u30b9\u306b\u5bfe\u5fdc\u3057\u305f`Validator`\u3092\u5b9a\u7fa9\u3059\u308b(\u4ee5\u4e0b\u305d\u306eValidator\u3092`VMyClass`\u3068\u3059\u308b)\r\n1. `VMyClass`\u3068`Converter`\u3092\u7d99\u627f\u3057\u305f`CMyClass`\u3092\u5b9a\u7fa9\u3059\u308b\r\n1. [\u4f7f\u3044\u65b9](#\u4f7f\u3044\u65b9)\u3069\u304a\u308a\r\n\r\n\r\n<!-- omit in toc -->\r\n#### \u5b9f\u884c\u4f8b-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528\r\n\r\n<!-- no toc -->\r\n- [\u4f5c\u6210](#\u4f5c\u6210-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528)\r\n- [\u8aad\u307f\u8fbc\u307f](#\u8aad\u307f\u8fbc\u307f-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528)\r\n\r\n\r\n<!-- omit in toc -->\r\n##### \u4f5c\u6210-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528\r\n\r\n[\u5b9f\u884c\u4f8b](#\u5b9f\u884c\u4f8b-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528)\u306b\u623b\u308b  \r\n\r\n`my_company.json`\u3068\u3044\u3046\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u3066\u3044\u304d\u307e\u3059\u3002  \r\n\r\n`ConfigurationManager`\u3067\u306f`json.dump`\u3067\u304d\u306a\u3044\u5c5e\u6027\u306f`otsucfgmng.funcs.support_json_dump`\u95a2\u6570\u3067\u5909\u63db\u3092\u8a66\u307f\u307e\u3059(\u203b\u72ec\u81ea\u306b\u6307\u5b9a\u3057\u306a\u3044\u9650\u308a)  \r\n\u3053\u306e\u95a2\u6570\u3067\u306f`to_json`\u3092\u6301\u3064\u30af\u30e9\u30b9\u3092`cls.to_json`\u3067\u3001\u305d\u308c\u4ee5\u5916\u306e\u30af\u30e9\u30b9\u3092`str(cls)`\u3067\u5909\u63db\u3057\u307e\u3059\u3002  \r\n\u306a\u306e\u3067\u3001`cls.to_json`\u3067\u8fd4\u308b\u5024\u3092`cls`\u306b\u5fa9\u5143\u3067\u304d\u308b\u3088\u3046\u306a`Converter`\u3092\u5b9a\u7fa9\u3059\u308c\u3070\u8aad\u307f\u8fbc\u307f\u6642\u306b\u5fa9\u5143\u3055\u308c\u307e\u3059\u3002\r\n\r\n```python\r\n\r\n# 1. & 1.1.\r\nfrom typing import Any\r\n\r\nfrom otsuvalidator import CNoneable\r\nfrom otsuvalidator.bases import Converter, Validator\r\n\r\nfrom otsucfgmng import BaseCM\r\n\r\n\r\n# 2.\r\nclass Person:\r\n    # 2.1.\r\n    def __init__(self, name: str, age: int, gender: str):\r\n        self.name = name\r\n        self.age = age\r\n        self.gender = gender\r\n\r\n    def show_profile(self):\r\n        print(self)\r\n\r\n    # 2.2.\r\n    def __str__(self) -> str:\r\n        data = (\r\n            ('\u540d\u524d', self.name),\r\n            ('\u5e74\u9f62', self.age),\r\n            ('\u6027', self.gender),\r\n        )\r\n        prof = []\r\n        for k, v in data:\r\n            prof.append(f'{k}\\t: {v}')\r\n        prof = '\\n'.join(prof)\r\n        return prof\r\n\r\n    def to_json(self) -> dict:\r\n        data = {'name': self.name, 'age': self.age, 'gender': self.gender}\r\n        return data\r\n\r\n\r\n# 3.\r\nclass VPerson(Validator):\r\n    def validate(self, value: Any) -> Person:\r\n        if type(value) is not Person:\r\n            msg = self.ERRMSG('Person\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059', value)\r\n            raise TypeError(msg)\r\n        return value\r\n\r\n\r\n# 4.\r\nclass CPerson(VPerson, Converter):\r\n    def validate(self, value: Any) -> Person:\r\n        if type(value) is not Person:\r\n            try:\r\n                if isinstance(value, dict):\r\n                    value = Person(**value)\r\n                else:\r\n                    raise TypeError\r\n            except:\r\n                msg = self.ERRMSG('Person\u578b\u3068\u3057\u3066\u6271\u3048\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002', value)\r\n                raise TypeError(msg)\r\n        return super().validate(value)\r\n\r\n    def super_validate(self, value: Any) -> Person:\r\n        return super().super_validate(value)\r\n\r\n\r\n# 5.\r\nclass ConfigurationManager(BaseCM):\r\n    __defaults__ = {\r\n        'president': Person('\u5c71\u7530\u592a\u90ce', 28, '\u7537'),\r\n        'employee': {\r\n            'director': Person('\u90e8\u9577\u82b1\u5b50', 28, '\u5973'),\r\n            'manager': Person('\u8ab2\u9577\u5922', 28, '\u5973'),\r\n            'chief': Person('\u4fc2\u9577\u6b21\u90ce', 28, '\u7537')\r\n        }\r\n    }\r\n    president = CPerson()\r\n    director = CNoneable(CPerson())\r\n    manager = CNoneable(CPerson())\r\n    chief = CNoneable(CPerson())\r\n\r\n\r\nwith ConfigurationManager('my_company.json') as cm:\r\n    cm.president = Person('\u4e59\u516b', 28, '\u7537')\r\n    cm.director = Person('\u90e8\u9577\u5922', 28, '\u5973')\r\n    cm.manager = None\r\n    cm.chief = None\r\n```\r\n\r\n\u4e0a\u8a18\u306e\u51e6\u7406\u3067\u4f5c\u6210\u3055\u308c\u305f`my_company.json`\u306e\u4e2d\u8eab\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002  \r\n\r\n\r\n```json\r\n\r\n{\r\n    \"employee\": {\r\n        \"chief\": null,\r\n        \"manager\": null,\r\n        \"director\": {\r\n            \"name\": \"\u90e8\u9577\u5922\",\r\n            \"age\": 28,\r\n            \"gender\": \"\u5973\"\r\n        }\r\n    },\r\n    \"president\": {\r\n        \"name\": \"\u4e59\u516b\",\r\n        \"age\": 28,\r\n        \"gender\": \"\u7537\"\r\n    }\r\n}\r\n```\r\n\r\n\u5b9a\u7fa9\u901a\u308a`Person`\u30af\u30e9\u30b9\u306f`person.to_json`\u3092\u901a\u3057\u3066\u8f9e\u66f8\u5f62\u5f0f\u306b\u5909\u63db\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u304c\u308f\u304b\u308a\u307e\u3059\u3002\r\n\r\n<!-- omit in toc -->\r\n##### \u8aad\u307f\u8fbc\u307f-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528\r\n\r\n[\u5b9f\u884c\u4f8b](#\u5b9f\u884c\u4f8b-\u81ea\u4f5c\u30af\u30e9\u30b9\u306e\u4f7f\u7528)\u306b\u623b\u308b  \r\n\r\n```python\r\n\r\n# 1. & 1.1.\r\nfrom typing import Any\r\n\r\nfrom otsuvalidator import CNoneable\r\nfrom otsuvalidator.bases import Converter, Validator\r\n\r\nfrom otsucfgmng import BaseCM\r\n\r\n\r\n# 2.\r\nclass Person:\r\n    # 2.1.\r\n    def __init__(self, name: str, age: int, gender: str):\r\n        self.name = name\r\n        self.age = age\r\n        self.gender = gender\r\n\r\n    def show_profile(self):\r\n        print(self)\r\n\r\n    # 2.2.\r\n    def __str__(self) -> str:\r\n        data = (\r\n            ('\u540d\u524d', self.name),\r\n            ('\u5e74\u9f62', self.age),\r\n            ('\u6027', self.gender),\r\n        )\r\n        prof = []\r\n        for k, v in data:\r\n            prof.append(f'{k}\\t: {v}')\r\n        prof = '\\n'.join(prof)\r\n        return prof\r\n\r\n    def to_json(self) -> dict:\r\n        data = {'name': self.name, 'age': self.age, 'gender': self.gender}\r\n        return data\r\n\r\n\r\n# 3.\r\nclass VPerson(Validator):\r\n    def validate(self, value: Any) -> Person:\r\n        if type(value) is not Person:\r\n            msg = self.ERRMSG('Person\u578b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059', value)\r\n            raise TypeError(msg)\r\n        return value\r\n\r\n\r\n# 4.\r\nclass CPerson(VPerson, Converter):\r\n    def validate(self, value: Any) -> Person:\r\n        if type(value) is not Person:\r\n            try:\r\n                if isinstance(value, dict):\r\n                    value = Person(**value)\r\n                else:\r\n                    raise TypeError\r\n            except:\r\n                msg = self.ERRMSG('Person\u578b\u3068\u3057\u3066\u6271\u3048\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002', value)\r\n                raise TypeError(msg)\r\n        return super().validate(value)\r\n\r\n    def super_validate(self, value: Any) -> Person:\r\n        return super().super_validate(value)\r\n\r\n\r\n# 5.\r\nclass ConfigurationManager(BaseCM):\r\n    __defaults__ = {\r\n        'president': Person('\u5c71\u7530\u592a\u90ce', 28, '\u7537'),\r\n        'employee': {\r\n            'director': Person('\u90e8\u9577\u82b1\u5b50', 28, '\u5973'),\r\n            'manager': Person('\u8ab2\u9577\u5922', 28, '\u5973'),\r\n            'chief': Person('\u4fc2\u9577\u6b21\u90ce', 28, '\u7537')\r\n        }\r\n    }\r\n    president = CPerson()\r\n    director = CNoneable(CPerson())\r\n    manager = CNoneable(CPerson())\r\n    chief = CNoneable(CPerson())\r\n\r\n\r\nwith ConfigurationManager('my_company.json') as cm:\r\n    for i, key in enumerate(('president', 'director', 'manager', 'chief')):\r\n        if i:\r\n            print('-' * 75)\r\n        print(f'{key}\\n{getattr(cm,key)}')\r\n\r\n```\r\n\r\n```console\r\n\r\n### \u51fa\u529b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059 ###\r\npresident\r\n\u540d\u524d    : \u4e59\u516b\r\n\u5e74\u9f62    : 28\r\n\u6027      : \u7537\r\n---------------------------------------------------------------------------\r\ndirector\r\n\u540d\u524d    : \u90e8\u9577\u5922\r\n\u5e74\u9f62    : 28\r\n\u6027      : \u5973\r\n---------------------------------------------------------------------------\r\nmanager\r\nNone\r\n---------------------------------------------------------------------------\r\nchief\r\nNone\r\n```\r\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2021 Otsuhachi  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u6271\u3046\u30af\u30e9\u30b9\u3092\u751f\u6210\u3059\u308b\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3059\u3002",
    "version": "1.3.3.311",
    "split_keywords": [
        "python",
        "configurationmanager",
        "configure",
        "json"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "933d7c18e14c835a6c2376950764a61b838b0b28a452e9147e79ca97337d2b4f",
                "md5": "910db696f782b64aca0f84ff5c72b878",
                "sha256": "5c0898af1e0d7d8fd9f2a96e54387e20596d87ae7dc2f1a62d5e419d1ef15a52"
            },
            "downloads": -1,
            "filename": "otsucfgmng-1.3.3.311-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "910db696f782b64aca0f84ff5c72b878",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 12315,
            "upload_time": "2023-04-24T16:30:19",
            "upload_time_iso_8601": "2023-04-24T16:30:19.405945Z",
            "url": "https://files.pythonhosted.org/packages/93/3d/7c18e14c835a6c2376950764a61b838b0b28a452e9147e79ca97337d2b4f/otsucfgmng-1.3.3.311-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b8153569debdeef8a6496b721853a5647975c8937f7143521d401706bd5e87cc",
                "md5": "48feacd2355d64556933b4db0241a33f",
                "sha256": "f7dc9817a4adfa4a2bd9ebc0ef1cdbe98f0efb6b29f4287be4ddb8c6bfd64f33"
            },
            "downloads": -1,
            "filename": "otsucfgmng-1.3.3.311.tar.gz",
            "has_sig": false,
            "md5_digest": "48feacd2355d64556933b4db0241a33f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 15542,
            "upload_time": "2023-04-24T16:30:22",
            "upload_time_iso_8601": "2023-04-24T16:30:22.965874Z",
            "url": "https://files.pythonhosted.org/packages/b8/15/3569debdeef8a6496b721853a5647975c8937f7143521d401706bd5e87cc/otsucfgmng-1.3.3.311.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-24 16:30:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "Otsuhachi",
    "github_project": "OtsuConfigurationManager.git",
    "lcname": "otsucfgmng"
}
        
Elapsed time: 0.05924s