질문자 :Ivan
나는 다음과 같은 폴더 구조를 가지고 있습니다.
application ├── app │ └── folder │ └── file.py └── app2 └── some_folder └── some_file.py
file.py
에서 일부 기능을 가져오고 some_file.py
.
난 노력 했어
from application.app.folder.file import func_name
그 외 다양한 시도가 있었지만 지금까지는 제대로 가져오지 못했습니다. 어떻게 해야 하나요?
참고: 이 답변은 매우 구체적인 질문을 위한 것입니다. 검색 엔진에서 여기에 오는 대부분의 프로그래머에게 이것은 당신이 찾고 있는 답이 아닙니다. 일반적으로 검색 경로를 수정하는 대신 파일을 패키지로 구성합니다(다른 답변 참조).
기본적으로는 할 수 없습니다. 파일을 가져올 때 Python은 진입점 스크립트가 실행되는 디렉토리와 패키지 설치 디렉토리와 같은 위치를 포함하는 sys.path
만 검색합니다(실제로는 이것보다 조금 더 복잡 하지만 대부분의 경우를 다룹니다).
그러나 런타임에 Python 경로에 다음을 추가할 수 있습니다.
# some_file.py import sys # insert at 1, 0 is the script path (or '' in REPL) sys.path.insert(1, '/path/to/application/app/folder') import file
Cameron문제 없음:
from application.app.folder.file import func_name
folder
__init__.py
도 포함되어 있는지 확인하면 패키지로 포함될 수 있습니다. PYTHONPATH
에 대해 이야기하는지 잘 모르겠습니다.
joey질문에서와 같이 모듈이 병렬 위치에 있는 경우:
application/app2/some_folder/some_file.py application/app2/another_folder/another_file.py
이 속기는 한 모듈을 다른 모듈에서 볼 수 있도록 합니다.
import sys sys.path.append('../')
slizb먼저 name-file.py에서 sys 가져오기
import sys
두 번째 로 name-file.py에 폴더 경로를 추가합니다.
sys.path.insert(0, '/the/folder/path/name-package/')
세 번째 하위 디렉토리에 __ init __.py라는 빈 파일을 만듭니다(이는 Python에 패키지임을 알려줍니다).
네 번째 로 name-file.py의 폴더 안에 모듈을 가져옵니다.
from name-package import name-module
Alex Montoya임시 방법은 문서에 설명된 대로 환경 변수 PYTHONPATH
를 사용하는 것이라고 생각합니다. Python2 , Python3
# Linux & OSX export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH # Windows set PYTHONPATH=C:\path\to\dirWithScripts\;%PYTHONPATH%
Ax3l문제는 Python이 Python 디렉토리에서 이 파일을 찾고 있지만 찾지 못한다는 것입니다. Python 디렉토리가 아니라 현재 있는 디렉토리에 대해 말하고 있음을 지정해야 합니다.
이렇게 하려면 다음을 변경합니다.
from application.app.folder.file import func_name
이에:
from .application.app.folder.file import func_name
점을 추가하면 Python 디렉토리를 찾는 대신 이 폴더에서 애플리케이션 폴더를 찾으라는 의미입니다.
CianB여기에 대한 답변은 명확하지 않습니다. 이것은 Python 3.6에서 테스트되었습니다.
이 폴더 구조로:
main.py | ---- myfolder/myfile.py
myfile.py
에 내용이 있는 위치:
def myfunc(): print('hello')
main.py
의 import 문은 다음과 같습니다.
from myfolder.myfile import myfunc myfunc()
그러면 hello 가 인쇄됩니다.
danday74내가 아는 바에 따르면 가져오려는 함수의 폴더에 직접 __init__.py
Vaibhav SinghPython 3.4 이상에서는 소스 파일에서 직접 가져올 수 있습니다(문서 링크). 이것은 가장 간단한 솔루션은 아니지만 완전성을 위해 이 답변을 포함하고 있습니다.
다음은 예입니다. foo.py
라는 이름으로 가져올 파일입니다.
def announce(): print("Imported!")
문서의 예제에서 크게 영감을 받은 위의 파일을 가져오는 코드:
import importlib.util def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module foo = module_from_file("foo", "/path/to/foo.py") if __name__ == "__main__": print(foo) print(dir(foo)) foo.announce()
출력:
<module 'foo' from '/path/to/foo.py'> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce'] Imported!
변수 이름, 모듈 이름 및 파일 이름이 일치하지 않아도 됩니다. 이 코드는 여전히 작동합니다.
import importlib.util def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module baz = module_from_file("bar", "/path/to/foo.py") if __name__ == "__main__": print(baz) print(dir(baz)) baz.announce()
출력:
<module 'bar' from '/path/to/foo.py'> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce'] Imported!
프로그래밍 방식으로 모듈 가져오기는 Python 3.1에 도입되었으며 모듈을 가져오는 방법을 더 잘 제어할 수 있습니다. 자세한 내용은 설명서를 참조하십시오.
wecsamPython의 상대 가져오기를 시도합니다.
from ...app.folder.file import func_name
모든 선행 점은 현재 디렉토리에서 시작하는 계층 구조의 또 다른 상위 레벨입니다.
문제? 이것이 당신을 위해 작동하지 않는다면 아마도 당신은 많은 gotcha의 상대적 수입에 의해 비트를 얻고 있을 것입니다. 자세한 내용은 답변 및 의견 읽기: __init__.py를 사용하여 "비패키지에서 상대 가져오기 시도"를 수정하는 방법
힌트: 모든 디렉토리 수준에서 __init__.py
최상위 디렉토리에서 실행하거나 PYTHONPATH에 해당 최상위 디렉토리 python -m application.app2.some_folder.some_file
(.py 제외)이 필요할 수 있습니다. 휴!
Zectbumo특히 여러 파일을 가져올 때 동일한 문제에 직면했는데 이것이 제가 극복한 방법입니다.
import os, sys from os.path import dirname, join, abspath sys.path.insert(0, abspath(join(dirname(__file__), '..'))) from root_folder import file_name
Erick Mwazonga응용 프로그램을 다른 환경으로 이동할 때 절대 경로와 함께 sys.path.append
현재 작업 디렉토리는 스크립트가 호출된 방식에 따라 다르기 때문에 상대 경로를 사용하는 것이 항상 작동하는 것은 아닙니다.
응용 프로그램 폴더 구조가 고정되어 있으므로 os.path
를 사용하여 가져오려는 모듈의 전체 경로를 가져올 수 있습니다. 예를 들어 다음과 같은 구조인 경우:
/home/me/application/app2/some_folder/vanilla.py /home/me/application/app2/another_folder/mango.py
그리고 mango 모듈을 가져오려고 한다고 가정해 보겠습니다. 바닐라.py 에서 다음을 수행할 수 있습니다.
import sys, os.path mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + '/another_folder/') sys.path.append(mango_dir) import mango
물론 mango_dir 변수는 필요하지 않습니다.
이것이 어떻게 작동하는지 이해하려면 이 대화식 세션 예제를 보십시오.
>>> import os >>> mydir = '/home/me/application/app2/some_folder' >>> newdir = os.path.abspath(os.path.join(mydir, '..')) >>> newdir '/home/me/application/app2' >>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder' >>> >>> newdir '/home/me/application/app2/another_folder' >>>
그리고 os.path 문서를 확인하십시오.
또한 점으로 구분된 모듈 이름을 사용할 수 있으므로 packages 를 사용할 때 여러 폴더를 처리하는 것이 더 쉽다는 점도 주목할 가치가 있습니다.
NagevLinux의 python3에서 나를 위해 일했습니다.
import sys sys.path.append(pathToFolderContainingScripts) from scriptName import functionName #scriptName without .py extension
dsg38application
을 python 프로젝트의 루트 디렉토리로 간주하여 application
, app
및 folder
폴더 __init__.py
파일을 만듭니다. 그런 다음 some_file.py
에서 다음과 같이 변경하여 func_name의 정의를 가져옵니다.
import sys sys.path.insert(0, r'/from/root/directory/application') from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file. func_name()
ChandanK이것은 Windows에서 나를 위해 작동합니다.
# some_file.py on mainApp/app2 import sys sys.path.insert(0, sys.path[0]+'\\app2') import some_file
Emeeus제 경우에는 가져올 클래스가 있었습니다. 내 파일은 다음과 같습니다.
# /opt/path/to/code/log_helper.py class LogHelper: # stuff here
내 기본 파일에 다음을 통해 코드를 포함했습니다.
import sys sys.path.append("/opt/path/to/code/") from log_helper import LogHelper
schmudu패키지를 만드는 가장 좋은 방법은 최상위 디렉토리에서 main_module.py
와 같은 모듈에서 다른 모듈을 실행하고 액세스하는 것입니다.
main_module.py
사용하여 하위 패키지, 상위 패키지 또는 동일한 수준의 패키지 및 모듈을 사용하고 액세스할 수 있음을 보여줍니다.
테스트를 위해 다음 파일과 폴더를 만들고 실행합니다.
package/ | |----- __init__.py (Empty file) |------- main_module.py (Contains: import subpackage_1.module_1) |------- module_0.py (Contains: print('module_0 at parent directory, is imported')) | | |------- subpackage_1/ | | | |----- __init__.py (Empty file) | |----- module_1.py (Contains: print('importing other modules from module_1...') | | import module_0 | | import subpackage_2.module_2 | | import subpackage_1.sub_subpackage_3.module_3) | |----- photo.png | | | | | |----- sub_subpackage_3/ | | | |----- __init__.py (Empty file) | |----- module_3.py (Contains: print('module_3 at sub directory, is imported')) | |------- subpackage_2/ | | | |----- __init__.py (Empty file) | |----- module_2.py (Contains: print('module_2 at same level directory, is imported'))
이제 main_module.py
출력은
>>>'importing other modules from module_1...' 'module_0 at parent directory, is imported' 'module_2 at same level directory, is imported' 'module_3 at sub directory, is imported'
사진 및 파일 열기 참고:
패키지 구조에서 사진에 접근하려면 최상위 디렉토리에서 절대 디렉토리를 사용하십시오.
main_module.py
photo.png
내부에서 module_1.py
를 열고 싶다고 가정해 봅시다.
module_1.py
포함되어야 하는 내용은 다음과 같습니다.
옳은:
image_path = 'subpackage_1/photo.png' cv2.imread(image_path)
잘못된:
image_path = 'photo.png' cv2.imread(image_path)
module_1.py
와 photo.png
가 같은 디렉토리에 있지만.
Mohsen Haddadi저는 아주 특별합니다. 저는 Windows에서 Python을 사용합니다!
나는 단지 정보를 완성합니다. Windows와 Linux 모두에서 상대 경로와 절대 경로가 모두 sys.path
로 작동합니다(여러 PC와 다른 기본 디렉토리에서 내 스크립트를 사용하기 때문에 상대 경로가 필요합니다).
그리고 Windows를 사용할 때 \
및 /
둘 다 파일 이름의 구분 기호로 사용할 수 있으며 물론 \
를 Python 문자열로 두 배로 늘려야 합니다.
몇 가지 유효한 예:
sys.path.append('c:\\tools\\mydir') sys.path.append('..\\mytools') sys.path.append('c:/tools/mydir') sys.path.append('../mytools')
(참고 : Linux와 호환되고 Windows 탐색기에 작성하고 복사하는 것이 더 간단하기 때문에 'Windows-native'가 덜한 경우 /
\
, event 보다 더 편리하다고 생각합니다)
herve-guerin나는 같은 질문에 여러 번 부딪쳤으므로 내 솔루션을 공유하고 싶습니다.
파이썬 버전: 3.X
다음 솔루션은 2020년 1월 1일 이후 Python 2가 지원되지 않기 때문에 Python 버전 3.X에서 애플리케이션을 개발하는 사람을 위한 것입니다.
프로젝트 구조
파이썬 3에서는 암시적 네임스페이스 패키지 로 인해 프로젝트 하위 디렉토리에 __init__.py
가 필요하지 않습니다. Python 3.3+의 패키지에는 init .py가 필요하지 않음을 참조하십시오.
Project ├── main.py ├── .gitignore | ├── a | └── file_a.py | └── b └── file_b.py
문제 설명
에서 file_b.py
, 나는 클래스 가져올 것 A
에 file_a.py
폴더 아래에있는 A.
솔루션
#1 빠르지만 더러운 방법
현재 새 프로젝트를 개발 중인 것처럼 패키지를 설치하지 않고
try catch
를 사용하여 오류를 확인합니다. 코드 예:
import sys try: # The insertion index should be 1 because index 0 is this file sys.path.insert(1, '/absolute/path/to/folder/a') # the type of path is string # because the system path already have the absolute path to folder a # so it can recognize file_a.py while searching from file_a import A except (ModuleNotFoundError, ImportError) as e: print("{} fileure".format(type(e))) else: print("Import succeeded")
#2 패키지 설치
애플리케이션을 설치한 후(이 게시물에는 설치 튜토리얼이 포함되어 있지 않습니다)
당신은 단순히
try: from __future__ import absolute_import # now it can reach class A of file_a.py in folder a # by relative import from ..a.file_a import A except (ModuleNotFoundError, ImportError) as e: print("{} fileure".format(type(e))) else: print("Import succeeded")
즐거운 코딩!
WY Hsu특정 경로에서 모듈을 로드하는 목적이 사용자 정의 모듈을 개발하는 동안 도움이 되는 것이라면 사용자 정의 모듈의 루트를 가리키는 테스트 스크립트의 동일한 폴더에 기호 링크를 생성할 수 있습니다. 이 모듈 참조는 해당 폴더에서 실행되는 모든 스크립트에 대해 동일한 이름으로 설치된 다른 모듈보다 우선합니다.
나는 이것을 Linux에서 테스트했지만 심볼릭 링크를 지원하는 모든 최신 OS에서 작동해야 합니다.
이 접근 방식의 한 가지 장점은 자체 로컬 SVC 분기 작업 복사본에 있는 모듈을 가리킬 수 있다는 것입니다. 이를 통해 개발 주기 시간을 크게 단순화하고 다양한 버전의 모듈을 관리하는 오류 모드를 줄일 수 있습니다.
Timothy C. Quinn├───root │ ├───dir_a │ │ ├───file_a.py │ │ └───file_xx.py │ ├───dir_b │ │ ├───file_b.py │ │ └───file_yy.py │ ├───dir_c │ └───dir_n
PYTHONPATH
상위 디렉토리를 추가할 수 있습니다. sys.path
나열된 "모듈 검색 경로"에서 OS에 따라 경로를 사용할 수 있습니다. 따라서 다음과 같이 상위 디렉토리를 쉽게 추가할 수 있습니다.
# file_b.py import sys sys.path.insert(0, '..') from dir_a.file_a import func_name
Milovan Tomaševićimport ...
대신 다음을 수행하십시오.
from <MySubFolder> import <MyFile>
MyFile은 MySubFolder 안에 있습니다.
Galileoomega일반적으로 가져오려는 모듈에 대한 심볼릭 링크를 만듭니다. 심볼릭 링크는 Python 인터프리터가 현재 디렉토리(다른 모듈을 가져오는 스크립트) 내에서 모듈을 찾을 수 있는지 확인합니다. 나중에 작업이 끝나면 심볼릭 링크를 제거할 수 있습니다. 또한 .gitignore에서 심볼릭 링크를 무시해야 합니다. 그래야 심볼릭 링크된 모듈을 실수로 저장소에 커밋하지 않습니다. 이 접근 방식을 사용하면 실행 중인 스크립트와 병렬로 위치한 모듈로 성공적으로 작업할 수도 있습니다.
ln -s ~/path/to/original/module/my_module ~/symlink/inside/the/destination/directory/my_module
picmate 涅내가 프로젝트에서 일하는 내가 통해 설치하는 사용자를 싶었 a
pip install a
다음과 같은 파일 목록 :
. ├── setup.py ├── MANIFEST.in └── a ├── __init__.py ├── a.py └── b ├── __init__.py └── b.py
setup.py
from setuptools import setup setup ( name='a', version='0.0.1', packages=['a'], package_data={ 'a': ['b/*'], }, )
매니페스트.in
recursive-include b *.*
a/ 초기화 .py
from __future__ import absolute_import from aa import cats import ab
a/a.py
cats = 0
a/b/ 초기화 .py
from __future__ import absolute_import from abb import dogs
a/b/b.py
dogs = 1
MANIFEST.in
있는 디렉토리에서 다음을 실행하여 모듈을 설치했습니다.
python setup.py install
/moustache/armwrestle
의 완전히 다른 위치에서 다음을 실행할 수 있었습니다.
import a dir(a)
어느 것이 확인 a.cats
실제로 0을 같게하고 abdogs
의도 한대로 실제로 1 말았 네.
duhaimeimportlib를 사용하여 다음과 같은 문자열을 사용하여 폴더에서 모듈을 가져오려는 모듈을 가져올 수 있습니다.
import importlib scriptName = 'Snake' script = importlib.import_module('Scripts\\.%s' % scriptName)
이 예제에는 위의 코드인 main.py와 Scripts라는 폴더가 있으며 scriptName
변수를 변경하여 이 폴더에서 필요한 모든 것을 호출할 수 있습니다. script
를 사용하여 이 모듈을 참조할 수 있습니다. Hello()
라는 함수가 있는 경우 다음과 같이 하여 이 함수를 실행할 수 있습니다.
script.Hello()
나는 이것을 Python 3.6에서 테스트했습니다.
Dextron나는 이러한 문제를 여러 번 겪었습니다. 나는이 같은 페이지에 많이 왔습니다. 마지막 문제에서는 server
를 실행해야 했지만 디버깅할 때마다 다른 하위 디렉터리에서 실행하고 싶었습니다.
import sys sys.insert(1, /path)
다른 모듈에서 내가 같은 디렉토리에있는 모든이었다 다른 * .CSV 파일을 읽을했기 때문에 나를 위해 작동하지 않았다.
결국 나를 위해 일한 것은 파이썬이 아니었지만 다음과 같습니다.
나는 디버그하고 싶은 모듈 위에 if __main__
을 사용했는데, 이는 일반적인 경로와 다른 경로에서 실행됩니다.
그래서:
# On top of the module, instead of on the bottom import os if __name__ == '__main__': os.chdir('/path/for/the/regularly/run/directory')
B Furtado폴더와 하위 폴더가 여러 개인 경우 항상 기본 디렉토리 에서 모든 클래스 또는 모듈을 가져올 수 있습니다.
예: 프로젝트의 트리 구조
Project ├── main.py ├── .gitignore | ├── src ├────model | └── user_model.py |────controller └── user_controller.py
이제 main.py 파일의 user_model.py에서 "UserModel" 클래스를 가져오려면 다음을 사용하여 수행할 수 있습니다.
from src.model.user_model.py import UserModel
또한 같은 줄을 사용하여 user_controller.py 파일에서 같은 클래스를 가져올 수 있습니다.
from src.model.user_model.py import UserModel
전반적으로 프로젝트 디렉토리 내부에 파이썬 파일에서 수입 클래스와 파일에 대한 주요 프로젝트 디렉토리의 참조를 제공 할 수 있습니다.
kepy97누군가 여전히 솔루션을 찾고 있는 경우. 이것은 나를 위해 일했습니다.
Python은 실행하는 스크립트가 포함된 폴더를 PYTHONPATH에 추가하므로 다음을 실행하면
python application/app2/some_folder/some_file.py
application/app2/some_folder 폴더만 경로에 추가됩니다(명령을 실행하는 기본 디렉토리가 아님). 대신 파일을 모듈로 실행하고 some_folder 디렉토리에 __init__.py를 추가하세요.
python -m application.app2.some_folder.some_file
이렇게 하면 파이썬 경로에 기본 디렉토리가 추가되고 비상대적 가져오기를 통해 클래스에 액세스할 수 있습니다.
Md Shafiul Islam아래 코드는 위치에 관계없이 Python 버전 안전한 방식으로 경로에 의해 제공된 Python 스크립트를 가져옵니다.
def import_module_by_path(path): name = os.path.splitext(os.path.basename(path))[0] if sys.version_info[0] == 2: # Python 2 import imp return imp.load_source(name, path) elif sys.version_info[:2] <= (3, 4): # Python 3, version <= 3.4 from importlib.machinery import SourceFileLoader return SourceFileLoader(name, path).load_module() else: # Python 3, after 3.4 import importlib.util spec = importlib.util.spec_from_file_location(name, path) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) return mod
나는의 코드베이스에서 이것을 발견 psutils 라인 1042에서 psutils.test.__init__.py
(최근 대부분의 2020년 9월 10일의 확약).
사용 예:
script = "/home/username/Documents/some_script.py" some_module = import_module_by_path(script) print(some_module.foo())
중요한 경고: 모듈은 최상위 수준으로 처리됩니다. 상위 패키지의 상대 가져오기는 실패합니다.
Neinsteinf5를 눌러 Python 셸을 새로 고치거나 실행-> 모듈 실행으로 이동할 수 있습니다. 이렇게 하면 파일에서 무언가를 읽기 위해 디렉토리를 변경할 필요가 없습니다. Python은 자동으로 디렉토리를 변경합니다. 그러나 Python Shell에서 다른 디렉토리의 다른 파일로 작업하려면 앞서 Cameron이 말했듯이 sys에서 디렉토리를 변경할 수 있습니다.
IOstream출처 : http:www.stackoverflow.com/questions/4383571/importing-files-from-different-folder