etc./StackOverFlow

다른 폴더에서 파일 가져오기

청렴결백한 만능 재주꾼 2021. 12. 24. 06:18
반응형

질문자 :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에 패키지임을 알려줍니다).

  • 이름 파일.py
  • 이름 패키지
    • __ 초기화 __.py
    • 이름 모듈.py

네 번째 로 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 Singh

Python 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에 도입되었으며 모듈을 가져오는 방법을 더 잘 제어할 수 있습니다. 자세한 내용은 설명서를 참조하십시오.


wecsam

Python의 상대 가져오기를 시도합니다.

 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 를 사용할 때 여러 폴더를 처리하는 것이 더 쉽다는 점도 주목할 가치가 있습니다.


Nagev

Linux의 python3에서 나를 위해 일했습니다.

 import sys sys.path.append(pathToFolderContainingScripts) from scriptName import functionName #scriptName without .py extension

dsg38

application 을 python 프로젝트의 루트 디렉토리로 간주하여 application , appfolder 폴더 __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.pyphoto.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 , 나는 클래스 가져올 것 Afile_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 말았 네.


duhaime

importlib를 사용하여 다음과 같은 문자열을 사용하여 폴더에서 모듈을 가져오려는 모듈을 가져올 수 있습니다.

 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())

중요한 경고: 모듈은 최상위 수준으로 처리됩니다. 상위 패키지의 상대 가져오기는 실패합니다.


Neinstein

f5를 눌러 Python 셸을 새로 고치거나 실행-> 모듈 실행으로 이동할 수 있습니다. 이렇게 하면 파일에서 무언가를 읽기 위해 디렉토리를 변경할 필요가 없습니다. Python은 자동으로 디렉토리를 변경합니다. 그러나 Python Shell에서 다른 디렉토리의 다른 파일로 작업하려면 앞서 Cameron이 말했듯이 sys에서 디렉토리를 변경할 수 있습니다.


IOstream

출처 : http:www.stackoverflow.com/questions/4383571/importing-files-from-different-folder

반응형