폴더의 모든 모듈을 로드하는 방법
누군가가 나에게 전체 모듈 디렉토리를 가져올 수 있는 좋은 방법을 제공해 줄 수 있을까?
나는 이런 구조를 가지고 있다.
/Foo
bar.py
spam.py
eggs.py
단지 추가해서 패키지로 변환하려고 했다.__init__.py
하는 것과 하는 것from Foo import *
하지만 내가 바라던 대로 되지 않았다.
fythrough python 나na열() .py
) 파일을 현재 폴더에 저장한 다음__all__
에 있어서 가변적인.__init__.py
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
추가__all__
:__init__.py
포함:
__all__ = ["bar", "spam", "eggs"]
http://docs.python.org/tutorial/modules.html을 참조하십시오.
2017년 업데이트: 대신 사용하길 원할 것이다.
다음을 추가하여 Foo 디렉토리를 패키지로 만들기__init__.py
. 그 안에서.__init__.py
추가:
import bar
import eggs
import spam
동적(좋은 생각이거나 아닐 수도 있음)을 원하므로 모든 py 파일을 list dir와 함께 나열하고 다음과 같은 방법으로 가져오십시오.
import os
for module in os.listdir(os.path.dirname(__file__)):
if module == '__init__.py' or module[-3:] != '.py':
continue
__import__(module[:-3], locals(), globals())
del module
그런 다음 코드에서 다음을 수행하십시오.
import Foo
이제 다음 모듈로 액세스하십시오.
Foo.bar
Foo.eggs
Foo.spam
등from Foo import *
이름 충돌과 코드 분석을 어렵게 하는 등 여러 가지 이유로 좋은 생각이 아니다.
미하일의 대답을 확대하면서, 나는 (파일 경로를 직접 처리하지 않는, 안에서와 같이) 헤키쉬하지 않는 방법은 다음과 같다고 믿는다.
- 빈 곳을 만들다.
__init__.py
로 제출하다.Foo/
- 실행
import pkgutil
import sys
def load_all_modules_from_dir(dirname):
for importer, package_name, _ in pkgutil.iter_modules([dirname]):
full_package_name = '%s.%s' % (dirname, package_name)
if full_package_name not in sys.modules:
module = importer.find_module(package_name
).load_module(full_package_name)
print module
load_all_modules_from_dir('Foo')
다음과 같은 혜택을 누리십시오.
<module 'Foo.bar' from '/home/.../Foo/bar.pyc'>
<module 'Foo.spam' from '/home/.../Foo/spam.pyc'>
Python, 디렉터리 아래의 모든 파일 포함:
일하러 갈 수 없는 신참들을 위해서라면 손을 꼭 잡아줘야지
폴더 /home/el/foo를 만들고 파일 만들기
main.py
에 이 home/el/foo abra에 코드를를에에에오오오.from hellokitty import * spam.spamfunc() ham.hamfunc()
디렉터리 만들기
/home/el/foo/hellokitty
파일 만들기
__init__.py
밑에/home/el/foo/hellokitty
그리고 여기에 코드를 넣으세요:__all__ = ["spam", "ham"]
다음 두 개의 python 파일 만들기:
spam.py
그리고ham.py
밑에/home/el/foo/hellokitty
스팸 내부에 함수를 정의하십시오.py:
def spamfunc(): print("Spammity spam")
함수에 함수를 정의한다.py:
def hamfunc(): print("Upgrade from baloney")
실행:
el@apollo:/home/el/foo$ python main.py spammity spam Upgrade from baloney
나는 이 문제에 스스로 싫증이 나서, 그것을 고치기 위해 오토모디니트라는 소포를 썼다.http://pypi.python.org/pypi/automodinit/에서 받을 수 있다.
사용법은 다음과 같다.
- 다음 항목
automodinit
에 포장하다.setup.py
종속성 - 다음과 같이 모든 _init__py 파일을 교체하십시오.
__all__ = ["다시 쓰겠다"]# 위의 선이나 이 선은 수정하지 마!자동 초기화 가져오기오토모디네이션의automodinit(_name__, _file__, globals())자동판매기♪ 네가 원하는 건 뭐든 할 수 있어, 수정되지 않을 거야
바로 그거야!지금부터 모듈을 가져오면 모듈의 .py[co] 파일 목록으로 _all__이 설정되며, 다음과 같이 입력한 것처럼 각 파일을 가져오게 된다.
for x in __all__: import x
따라서 "M 가져오기 *에서"의 효과는 "M 가져오기"와 정확히 일치한다.
automodinit
내부 ZIP 아카이브에서 실행되어 행복하며 따라서 ZIP 안전하다.
니올
내가 꽤 오래된 게시물을 업데이트하고 있다는 걸 알아 그리고 난 사용하려고 노력했다.automodinit
그러나 python3의 설정 과정이 깨졌다는 것을 알게 되었다.그래서 루카의 대답을 바탕으로 이 문제에 대해 좀 더 간단한 답을 생각해 냈는데 - 이 문제는 .zip과 안 될 수도 있어. 그래서 여기서 공유해야겠다고 생각했다.
의 범위 내에서__init__.py
에서 전송하다.yourpackage
:
#!/usr/bin/env python
import os, pkgutil
__all__ = list(module for _, module, _ in pkgutil.iter_modules([os.path.dirname(__file__)]))
그리고 아래의 다른 패키지 안에yourpackage
:
from yourpackage import *
그러면 패키지 안에 놓여 있는 모든 모듈을 로딩하게 되고, 새 모듈을 작성하면 자동으로 가져오게 된다.물론 그런 것들을 조심해서 사용하라, 큰 힘이 있으면 큰 책임이 따른다.
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
for imp, module, ispackage in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
__import__(module)
나는 또한 이 문제에 직면했고 이것이 나의 해결책이었다.
import os
def loadImports(path):
files = os.listdir(path)
imps = []
for i in range(len(files)):
name = files[i].split('.')
if len(name) > 1:
if name[1] == 'py' and name[0] != '__init__':
name = name[0]
imps.append(name)
file = open(path+'__init__.py','w')
toWrite = '__all__ = '+str(imps)
file.write(toWrite)
file.close()
이 함수는 (제공된 폴더에) 명명된 파일을 생성함__init__.py
, 이 포함되어 있다.__all__
폴더의 모든 모듈을 포함하는 변수.
예를 들어, 나는 이름이 지정된 폴더를 가지고 있다.Test
다음을 포함하는:
Foo.py
Bar.py
그래서 스크립트에는 모듈을 가져올 것을 나는 다음과 같이 쓸 것이다.
loadImports('Test/')
from Test import *
이것은 모든 것을 수입할 것이다.Test
그리고__init__.py
줄을 지어 들어오다Test
이제 다음을 포함함:
__all__ = ['Foo','Bar']
제안된 개선사항과 함께 Anurag Uniyal이 대답하시오!
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import os
import glob
all_list = list()
for f in glob.glob(os.path.dirname(__file__)+"/*.py"):
if os.path.isfile(f) and not os.path.basename(f).startswith('_'):
all_list.append(os.path.basename(f)[:-3])
__all__ = all_list
네가 추가해야 할 유일한 것은
from importlib import import_module
from pathlib import Path
__all__ = [
import_module(f".{f.stem}", __package__)
for f in Path(__file__).parent.glob("*.py")
if "__" not in f.stem
]
del import_module, Path
지금까지 찾은 방법 중 가장 좋은 방법이야
from os.path import dirname, join, isdir, abspath, basename
from glob import glob
pwd = dirname(__file__)
for x in glob(join(pwd, '*.py')):
if not x.startswith('__'):
__import__(basename(x)[:-3], globals(), locals())
몇 가지 수정 사항이 있는 아누라크의 예:
import os, glob
modules = glob.glob(os.path.join(os.path.dirname(__file__), "*.py"))
__all__ = [os.path.basename(f)[:-3] for f in modules if not f.endswith("__init__.py")]
언제from . import *
충분치 않아, 테드의 대답보다 나아진 거야.구체적으로, 의 사용__all__
이 접근방식은 필요하지 않다.
"""Import all modules that exist in the current directory."""
# Ref https://stackoverflow.com/a/60861023/
from importlib import import_module
from pathlib import Path
for f in Path(__file__).parent.glob("*.py"):
module_name = f.stem
if (not module_name.startswith("_")) and (module_name not in globals()):
import_module(f".{module_name}", __package__)
del f, module_name
del import_module, Path
:module_name not in globals()
모듈을 이미 가져온 경우 주기적 가져오기가 위험할 수 있으므로 모듈을 다시 가져오지 않도록 하기 위함입니다.
네 것을 보아라.__init__.py
규정하다__all__
. 모듈 - 패키지 문서에 따르면
그
__init__.py
파일은 Python이 디렉토리를 포함된 패키지로 처리하도록 하는데 필요하다. 이는 문자열과 같이 공통 이름을 가진 디렉토리가 나중에 모듈 검색 경로에서 발생하는 유효한 모듈을 의도치 않게 숨기는 것을 방지하기 위해 이루어진다.가장 간단한 경우,__init__.py
빈 파일일 수도 있지만, 패키지에 대한 초기화 코드를 실행하거나__all__
변수(나중에 설명함)....
유일한 해결책은 패키지 작성자가 패키지의 명시적 색인을 제공하는 것이다.
__init__.py
코드는 명명된 목록을 정의한다.__all__
패키지 가져오기 *에서 가져올 모듈 이름 목록으로 간주된다.패키지의 새 버전이 출시될 때 이 목록을 최신 상태로 유지하는 것은 패키지 작성자의 몫이다.또한 패키지 작성자는 해당 패키지에서 *를 가져오는 용도가 보이지 않는 경우 이를 지원하지 않기로 결정할 수 있다.예를 들어, 파일sounds/effects/__init__.py
다음 코드를 포함할 수 있다.
__all__ = ["echo", "surround", "reverse"]
라는 뜻일 것이다.
from sound.effects import *
소리 패키지의 세 개의 명명된 하위 품종을 가져올 것이다.
내가 그런 모듈을 만들었는데, 그 모듈에는 의존하지 않는다.__init__.py
(또는 다른 보조 파일)을 입력하여 다음 두 줄만 입력하도록 하십시오.
import importdir
importdir.do("Foo", globals())
자유롭게 재사용하거나 기여하십시오. http://gitlab.com/aurelien-lourot/importdir
아누라그 유니얄의 대답에 덧붙이고 싶다.당신은 그것을 훨씬 더 간단하게 만들 수 있고 많은 수입품들을 없앨 수 있다.__init__py 파일의 내용:
from os import listdir
from os.path import dirname
__all__ = [i[:-3] for i in listdir(dirname(__file__)) if not i.startswith('__') and i.endswith('.py')]
표준 라이브러리에 있는 pkgutil 모듈을 보십시오.그것은 당신이 원하는 것을 할 수 있게 해줄 것이다.__init__.py
디렉토리에 철하다그__init__.py
파일이 비어 있을 수 있다.
가져오기를 limportlib으로 가져와서 다음에 추가하십시오.__all__
(add
동작은 선택 사항)에서 반복적으로__init__.py
꾸러미의
/Foo
bar.py
spam.py
eggs.py
__init__.py
# __init__.py
import os
import importlib
pyfile_extes = ['py', ]
__all__ = [importlib.import_module('.%s' % filename, __package__) for filename in [os.path.splitext(i)[0] for i in os.listdir(os.path.dirname(__file__)) if os.path.splitext(i)[1] in pyfile_extes] if not filename.startswith('__')]
del os, importlib, pyfile_extes
중첩된 디렉토리 구조를 가지고 있었다.나는 파이톤 모듈이 들어 있는 메인 디렉토리 안에 여러 개의 디렉토리를 가지고 있었다.
나는 다음과 같은 대본을 내 대본에 추가했다.__init__.py
모든 모듈을 가져오기 위해 파일 작성
import glob, re, os
module_parent_directory = "path/to/the/directory/containing/__init__.py/file"
owd = os.getcwd()
if not owd.endswith(module_parent_directory): os.chdir(module_parent_directory)
module_paths = glob.glob("**/*.py", recursive = True)
for module_path in module_paths:
if not re.match( ".*__init__.py$", module_path):
import_path = module_path[:-3]
import_path = import_path.replace("/", ".")
exec(f"from .{import_path} import *")
os.chdir(owd)
아마도 이것을 이루기 위한 가장 좋은 방법은 아니지만, 나는 다른 어떤 것도 나에게 효과가 있도록 할 수 없었다.
참조URL: https://stackoverflow.com/questions/1057431/how-to-load-all-modules-in-a-folder
'programing' 카테고리의 다른 글
요소를 허용하려면 이 구성 요소의 '@NgModule.Schemas'에 'NO_ERRESS_SCHEMA'를 추가하십시오. (0) | 2022.03.07 |
---|---|
'v-built' 지시어는 어떤 수식어도 지원하지 않는다. (0) | 2022.03.07 |
라우터 v4를 사용하여 위치 변경에 대한 작업을 디스패치하는 방법 (0) | 2022.03.07 |
페이지 새로 고침 없이 Vuex 상태가 업데이트되지 않음 (0) | 2022.03.07 |
정적 함수를 Ract ES6 클래스로 호출 (0) | 2022.03.07 |