복붙노트

[PYTHON] 패키지 내의 모든 모듈 구성원을 가져 오는 방법은 무엇입니까?

PYTHON

패키지 내의 모든 모듈 구성원을 가져 오는 방법은 무엇입니까?

나는 다음과 유사한 파일 구조를 가진 패키지를 개발 중이다.

test.py
package/
    __init__.py
    foo_module.py
    example_module.py

test.py에서 가져 오기 패키지를 호출하면 패키지 모듈이 다음과 같이 나타나길 원합니다.

>>> vars(package)
mapping_proxy({foo: <function foo at 0x…}, {example: <function example at 0x…})

즉, 패키지에있는 모든 모듈의 멤버가 패키지의 네임 스페이스에 있어야하고 모듈 자체가 네임 스페이스에 있어야하는 것은 아닙니다. 패키지가 하위 패키지가 아닙니다.

내 파일을 다음과 같이 보자.

foo_module.py:

def foo(bar):
    return bar

example_module.py:

def example(arg):
    return foo(arg)

test.py:

print(example('derp'))

test.py, example_module.py 및 __init__.py에서 패키지 디렉토리 외부 (즉, test.py)와 패키지 자체 (즉, foo_module.py 및 example_module.py)에서 가져 오기 구문을 구조화하려면 어떻게해야합니까? 내가 시도한 모든 것은 부모 모듈에 ''로드되지 않았거나 상대 가져 오기를 수행 할 수 없거나 ImportError : 모듈에 'module_name'이 없습니다.

또한 PEP 8에서와 같이 : "패키지 내 수입품에 대한 상대적 수입은 절대적으로 권장되지 않습니다. 모든 수입품에 절대 패키지 경로를 사용하십시오. 이제 PEP 328은 Python 2.5에서 완벽하게 구현됩니다. 절대적인 수입은 더 이식 가능하고 일반적으로 더 읽기 쉽다. "

나는 파이썬 3.3을 사용하고있다.

해결법

  1. ==============================

    1.너는 말했다 :

    너는 말했다 :

    필자는 Python 2에서 사용했던 것을 플러그인을 자동으로 가져 와서 Python 3에서 작동하도록 조정함으로써 그렇게 할 수있었습니다.

    패키지의 __init__.py 파일은 같은 패키지 디렉토리에있는 '_'(밑줄) 문자로 시작하지 않는 다른 모든 파이썬 파일을 가져옵니다. 그런 다음 가져온 모듈의 네임 스페이스에있는 모든 이름을 __init__ 모듈의 이름에 추가합니다 (패키지의 네임 스페이스이기도 함). 참고 example_module 모듈을 foo_module에서 foo를 명시 적으로 가져와야했습니다.

    이런 식으로 일하는 한 가지 중요한 점은 패키지 모듈 이름이 동적이며 __init__.py 파일에 패키지 코드 이름을 하드 코딩 할 필요가 없다는 것을 깨닫는 것입니다. 물론 이것은 더 많은 코드를 필요로하지만 또한 추가 모듈을 추가 할 때 자동으로 새 모듈을 가져오고 모든 모듈에서 가져온 모듈을 가져 오지 못하도록하므로 모든 코드 (단일 레벨 패키지)에 대해 매우 일반적으로 작업 할 수 있습니다. 예배 규칙서.

    test.py:

    from package import *
    
    print(example('derp'))
    

    __init__.py:

    def _import_all_modules():
        """dynamically imports all modules in the package"""
        import traceback
        import os
        global __all__
        __all__ = []
        globals_, locals_ = globals(), locals()
    
        # dynamically import all the package modules
        for filename in os.listdir(__name__):
            # process all python files in directory that don't start with underscore
            # (which also keeps this module from importing itself)
            if filename[0] != '_' and filename.split('.')[-1] in ('py', 'pyw'):
                modulename = filename.split('.')[0]  # filename without extension
                package_module = '.'.join([__name__, modulename])
                try:
                    module = __import__(package_module, globals_, locals_, [modulename])
                except:
                    traceback.print_exc()
                    raise
                for name in module.__dict__:
                    if not name.startswith('_'):
                        globals_[name] = module.__dict__[name]
                        __all__.append(name)
    
    _import_all_modules()
    

    foo_module.py:

    def foo(bar):
        return bar
    

    example_module.py:

    from package.foo_module import foo  # added
    
    def example(arg):
        return foo(arg)
    
  2. ==============================

    2.모듈 가져 오기 이름 스타일 가져 오기를 사용하여 네임 스페이스를 어지럽히 지 않고도 필요한 값을 얻을 수 있다고 생각합니다. 나는 당신이 요구하고있는 것들에 대해 이러한 수입이 효과가있을 것이라고 생각한다.

    모듈 가져 오기 이름 스타일 가져 오기를 사용하여 네임 스페이스를 어지럽히 지 않고도 필요한 값을 얻을 수 있다고 생각합니다. 나는 당신이 요구하고있는 것들에 대해 이러한 수입이 효과가있을 것이라고 생각한다.

    example_module.py에 대한 가져 오기 :

    from package.foo_module import foo
    

    __init__.py에 대한 수입 :

    from package.foo_module import foo
    from package.example_module import example
    
    __all__ = [foo, example] # not strictly necessary, but makes clear what is public
    

    test.py에 대한 수입 :

    from package import example
    

    이것은 test.py (또는 패키지 계층의 같은 레벨에있는 다른 것)를 실행하는 경우에만 작동합니다. 그렇지 않으면 패키지를 포함하고있는 폴더가 파이썬 모듈 검색 경로에 있는지 확인해야합니다 (Python이 찾을 패키지를 설치하거나 sys.path에 적절한 폴더를 추가하여 패키지를 설치해야합니다).

  3. from https://stackoverflow.com/questions/14426574/how-to-import-members-of-all-modules-within-a-package by cc-by-sa and MIT license