61286


以下のようなディレクトリ構成

[code]

    model
    ├── __init__.py
    ├── supplement.py
    ├── supplement_name.py
    ├── supplement_property.py
    └── vitamin.py
    
[/code]

で、`supplement.py`から他のディレクトリ

  * supplement_name.py
  * supplement_property.py
  * vitamin.py

を以下のように **model** パッケージとして呼び出したいと考えています。

[code]

    from model import Vitamin, SupplementProperty, SupplementName
    
[/code]

しかし、この呼び出し方だと以下のようなエラーが出てimportに失敗します。

[code]

    > py model/supplement.py 
    Traceback (most recent call last):
      File "model/supplement.py", line 3, in <module>
        from model import Vitamin, SupplementProperty, SupplementName
    ModuleNotFoundError: No module named 'model'
    Error in sys.excepthook:
    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
        from apport.fileutils import likely_packaged, get_recent_crashes
      File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
        from apport.report import Report
      File "/usr/lib/python3/dist-packages/apport/report.py", line 30, in <module>
        import apport.fileutils
      File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 23, in <module>
        from apport.packaging_impl import impl as packaging
      File "/usr/lib/python3/dist-packages/apport/packaging_impl.py", line 24, in <module>
        import apt
      File "/usr/lib/python3/dist-packages/apt/__init__.py", line 23, in <module>
        import apt_pkg
    ModuleNotFoundError: No module named 'apt_pkg'
    
    Original exception was:
    Traceback (most recent call last):
      File "model/supplement.py", line 3, in <module>
        from model import Vitamin, SupplementProperty, SupplementName
    ModuleNotFoundError: No module named 'model'
    
[/code]

import方法を以下のような方式で行えばエラーは発生しません。

[code]

    from supplement_name import SupplementName
    from supplement_property import SupplementProperty
    from vitamin import Vitamin
    
[/code]

supplement.pyの内容は以下のようになっています。

[code]

    from dataclasses import dataclass
    
    from model import Vitamin, SupplementProperty, SupplementName
    # from supplement_name import SupplementName
    # from supplement_property import SupplementProperty
    # from vitamin import Vitamin
    
    
    @dataclass(frozen=True)
    class Supplement:
        id: str
        name: SupplementName
        prop: SupplementProperty
        vitamin: Vitamin
    
    
    if __name__ == '__main__':
        s = Supplement(
            id='test',
            name=SupplementName(code='test', detail='test-detail'),
            prop=SupplementProperty(price=100, tablet_num=100, manufacture='test-mn'),
            vitamin=Vitamin(va=1000)
        )
        print(s)
    
    
[/code]

__init__.pyの内容

[code]

    from .supplement import Supplement
    from .vitamin import Vitamin
    from .supplement_property import SupplementProperty
    from .supplement_name import SupplementName
    
[/code]

`python -m model.supplement`と実行した場合、以下のようなエラーが出ます。

[code]

    /usr/bin/python3.7: Error while finding module specification for 'model.supplement' (ImportError: cannot import name 'Vitamin' from 'model' (/home/tan/repositories/healthcare/backend/model/__init__.py))
    
[/code]

**model** というパッケージ単位でのimport方法があれば教えて下さい。


CC BY-SA 4.0
2019-12-09T18:26:01.447
61278
2019-12-10T02:12:50.910
2019-12-09T19:56:58.077
9616
9616
question
python python3
パッケージ単位でのインポート方法について


※ 以下、回答ではなく、コメントでのやり取りの補足になります

`__init__.py` の最後に `from .supplement import Supplement` を置いて `python3 -m
model.supplement` を実行しますと、

[code]

    from .vitamin import Vitamin
    from .supplement_property import SupplementProperty
    from .supplement_name import SupplementName
    from .supplement import Supplement   ## <--- Here
    
[/code]

以下の様なワーニングメッセージが表示されます。

[code]

    /usr/lib/python3.7/runpy.py:125: RuntimeWarning: 'model.supplement' found in
    sys.modules after import of package 'model', but prior to execution of
    'model.supplement'; this may result in unpredictable behaviour
    warn(RuntimeWarning(msg))
    
[/code]

つまり、`double import` になっている事が原因です。

この件に関しては、以下の回答が参考になります。

[Python 3.6 project structure leads to
RuntimeWarning](https://stackoverflow.com/a/45070583)


CC BY-SA 4.0
2019-12-10T02:12:50.910
61286
2019-12-10T02:12:50.910
61278
answer