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


1402

다음과 같은 폴더 구조가 있습니다.

application/app/folder/file.py

file.py의 일부 함수를 다른 파이썬 파일에 가져오고 싶습니다 .

application/app2/some_folder/some_file.py

난 노력 했어

from application.app.folder.file import func_name

그리고 다른 여러 가지 시도가 있었지만 지금까지 제대로 가져올 수 없었습니다. 어떻게해야합니까?



공식 문서를 읽으면 많은 도움이되었습니다! docs.python.org/3/reference/…
Kavin Raju S

답변:


1438

기본적으로 할 수 없습니다. 파일을 가져올 때 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

355
sys.path.append('/path/to/application/app/folder')is clean
pseudosudo

387
@pseudosudo : 그렇습니다. 그러나 처음에 경로를 삽입하면 이름 충돌시 경로가 다른 경로 (내장 된 경로)보다 먼저 검색되도록 보장 할 수 있습니다.
카메론

8
@kreativitea- sys.patha list가 아닌을 반환하며 를 a 및 뒤로 deque변환하는 것은 어리석은 일 입니다. listdeque
ArtOfWarfare

37
폴더의 .py 파일을 관리하는 pythonic 방법으로 간주됩니까? 궁금합니다. 왜 기본적으로 지원되지 않습니까? 모든 .py 파일을 단일 디렉토리에 유지하는 것은 의미가 없습니다.
Ofir

49
@ Ofir : 아니오, 이것은 좋은 깨끗한 pythonic 솔루션이 아닙니다. 일반적으로 디렉토리 트리를 기반으로하는 패키지를 사용해야합니다. 이 답변은 요청 된 질문에만 해당되며 어떤 이유로 든 많은 업 보트가 계속 발생합니다.
카메론

709

아무 문제가 없습니다 :

from application.app.folder.file import func_name

folder포함하고 있는지 확인 __init__.py하면 패키지로 포함될 수 있습니다. 다른 답변이 왜 이야기하는지 잘 모르겠습니다 PYTHONPATH.


47
수정 PYTHONPATH이 필요한 경우는 다루지 않기 때문입니다. 같은 수준에서 두 개의 폴더를 가지고 말 : AB. A가 있습니다 __init.py__. B내 에서 무언가를 가져 오십시오 A.
msvalkon

32
init.py또는 __init__.py파일 안에 무엇이 있습니까?
Lorem Ipsum Dolor 2

47
@Xinyang 빈 파일 일 수 있습니다. 그것의 존재는 파이썬에게 디렉토리를 패키지로 취급하도록 지시합니다.
jay

9
물론이 답변이 있다고 가정 application하고 app패키지가 (이 이미 당신을 즉 이미 __init__.py둘 다에서). 가산의 결과 __init__.py에도 folder, application.app.folderA (부)된다 패키지 사용자가 액세스 할 수있는, 모듈 application.app.folder.file 기호 func_name지금 가져올 수
Yibo 양

29
내가 무엇을 시도해도 작동하지 않습니다. "형제"디렉토리에서 가져 오려고합니다. 부모를 포함하여 모두 __ init __.py가 있습니다. 이 파이썬 3에만 해당됩니까?
dasWesen 2016 년

109

질문과 같이 모듈이 병렬 위치에있는 경우 :

application/app2/some_folder/some_file.py
application/app2/another_folder/another_file.py

이 속기는 하나의 모듈을 다른 모듈에서 볼 수있게합니다.

import sys
sys.path.append('../')

24
주의 사항 : 가져 오기 스크립트가 포함 디렉토리에서 실행되는 한 작동합니다. 그렇지 않으면 스크립트가 실행되는 다른 디렉토리의 상위 디렉토리가 경로에 추가되고 가져 오기에 실패합니다.
Carl Smith

14
이를 피하기 위해 파일의 상위 디렉토리를 얻을 수 있습니다sys.path.append(os.path.dirname(os.path.abspath(__file__)))
Rahul

그것은 나를 위해 작동하지 않았다 - 나는 실행 그래서, 부모까지 다시 올라 거기에 추가로이 dirname를 추가했다 cli/foo.py명령 줄에서하는 것은 할 수 있었다import cli.bar
RCross

2
@Rahul이 솔루션은 대화 형 쉘이 작동하지 않습니다
towi_parallelism

루트 폴더 (예 : 응용 프로그램 폴더)에서 실행하면 sys.path.append('.')을 사용하여 모듈을 가져 오는 것이 from app2.some_folder.some_file import your_function좋습니다. 또는 나를 위해 작동하는 것은 python3 -m app2.another_folder.another_file루트 폴더에서 실행 중 입니다.
중독

68

name-file.py에서 첫 번째 sys 가져 오기

 import sys

두 번째 로 name-file.py에 폴더 경로를 추가하십시오.

sys.path.insert(0, '/the/folder/path/name-package/')

셋째 하위 디렉토리에 __ init __.py라는 빈 파일을 만듭니다 (파이썬에게 패키지임을 알려줍니다)

  • name-file.py
  • 이름 패키지
    • __ init __.py
    • name-module.py

네 번째 는 name-file.py의 폴더 안에 모듈을 가져옵니다.

from name-package import name-module

5
name-file.py 바로 아래에 이름 폴더가 있으면 sys.path.insert-command 없이도 작동합니다 . 따라서 이름 폴더가 임의의 위치에있는 경우 에도이 솔루션이 작동하면 대답은 의문의 여지가 있습니다.
Bastian 2019

55

필자 는 설명서에 설명 된대로 환경 변수PYTHONPATH 를 사용 하는 것이 임시 방법이라고 생각합니다 : Python2 , Python3

# Linux & OSX
export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH

# Windows
set PYTHONPATH=C:\path\to\dirWithScripts\;%PYTHONPATH%

잠깐, myScripts를 파일 이름으로 바꾸겠습니까?
Vladimir Putin

4
아니요, .py 파일의 디렉토리 경로
Ax3l

1
불행히도 Anaconda를 사용하는 경우 PYTHONPATH가 실제로 내부적으로 사용되지 않으므로 작동하지 않습니다!
information_interchange

(최근)가 아나콘다의 변화를,이 작품 차선책을위한 워크 플로우 및 의견 SO 참조 : stackoverflow.com/questions/17386880/...는 일반적으로, 빌드를 대신 가져 오기 DIRS 해킹의 작은 패키지를 설치합니다.
Ax3l

46

여기에 대한 답변이 명확하지 않습니다 .Python 3.6에서 테스트되었습니다.

이 폴더 구조로 :

main.py
|
---- myfolder/myfile.py

myfile.py내용이있는 곳 :

def myfunc():
    print('hello')

수입 명세서 main.py는 다음과 같습니다.

from myfolder.myfile import myfunc
myfunc()

그러면 hello 가 인쇄 됩니다.


9
myfolder에 init .py (빈) 구성 파일을 추가하면 Linux (y)에서 작동했습니다.
Vincent

7
@Vincent은 무슨 뜻 __init__.py인가요?
mrgloom

2
@mrgloom 참으로
빈센트

3
어떤 이유로 든 추가 __init__.py가 작동하지 않습니다. 우분투 18에서 Py 3.6.5를 사용하고 있습니다. Pycharm에서는 작동하지만 터미널에서는 작동하지 않습니다.
Crearo Rotar

9
이것은 현재 작업 디렉토리와 다른 파일 트리의 분기에서 파일을 가져 오는 것에 대한 질문과는 전혀 관련이 없습니다.
Alexander Rossa

44

문제는 파이썬이 파이썬 디렉토리 에서이 파일을 찾고 찾지 못한다는 것입니다. 파이썬이 아닌 디렉토리에 대해 이야기하도록 지정해야합니다.

이렇게하려면 다음을 변경하십시오.

from application.app.folder.file import func_name

이에:

from .application.app.folder.file import func_name

점을 추가하면 Python 디렉토리를 찾는 대신이 폴더에서 응용 프로그램 폴더를 찾으십시오.


2
이것은 나를 고쳤다
Phi

32

내가 아는 것에서 __init__.py가져 오려는 함수 폴더에 직접 파일을 추가 하면 작업이 수행됩니다.


7
다른 디렉토리를 포함하려는 스크립트가 이미 sys.path에있는 경우에만
Ax3l

2
내가 사용하는 sys.path.append(tools_dir)윈도우와 내가 추가 할 필요가 없습니다 __init__.py' file in my directory tools_dir`을
에르베-GUERIN

25

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


11
아무도 이것을 이해하려고 노력했는지는 모르겠지만 너무 복잡하다고 생각합니다.
Dan

23

리눅스의 python3에서 나를 위해 일했습니다.

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

6
sys.path.append("/home/linux/folder/")— 바로 가기를 사용하지 마십시오."~/folder/"
daGo

22

파이썬의 상대 수입품을보십시오 :

from ...app.folder.file import func_name

모든 선행 점은 현재 디렉토리로 시작하는 계층 구조의 또 다른 상위 레벨입니다.


문제? 이것이 효과가 없다면 아마도 많은 수입차의 수입품에 약간의 영향을 받고있을 것입니다. 자세한 내용은 답변과 의견을 읽으십시오. __init__.py를 사용하여 "패키지가 아닌 다른 가져 오기 시도"를 수정하는 방법

힌트 : __init__.py모든 디렉토리 수준에 있어야 합니다. python -m application.app2.some_folder.some_file최상위 디렉토리에서 실행하거나 PYTHONPATH에 해당 최상위 디렉토리 가있는 (.py 제외) 필요할 수 있습니다 . 휴!


22

특히 여러 파일을 가져올 때 동일한 문제에 직면했습니다. 이것이 내가 극복 한 방법입니다.

import os, sys

from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))

from root_folder import file_name

2
일반적인 수입품과 다른 점을 설명 할 수 있다면 더 도움이 될 것입니까?
not2qubit

1
/path/dir1/__init__.py 및 /path/dir1/mod.py가 있습니다. dir1.mod의 /path/some.py의 경우 import func가 작동했습니다. /path/dir2/some.py에있을 때 위의 답변을 파일 맨 위에 복사하여 붙여 넣은 후에 만 ​​작동했습니다. 내가 가진 모든 파이썬 프로젝트가 / path /에있는 것은 아니기 때문에 경로를 편집하고 싶지 않았습니다.
jwal

19

고려 application파이썬 프로젝트의 루트 디렉토리로, 빈 생성 __init__.py에있는 파일 application, appfolder폴더를. 그런 다음 some_file.pyfunc_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()

sys.path.insert (0, r '/ from / root / directory')
Bolaka

18

응용 프로그램을 다른 환경으로 이동할 때 절대 경로와 함께 sys.path.append를 사용하는 것은 적합하지 않습니다. 현재 작업 디렉토리가 스크립트 호출 방법에 따라 다르므로 상대 경로를 사용하는 것이 항상 작동하지는 않습니다.

응용 프로그램 폴더 구조는 고정되어 있으므로 os.path를 사용하여 가져올 모듈의 전체 경로를 얻을 수 있습니다. 예를 들어, 이것이 구조 인 경우 :

/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py

"망고"모듈을 가져오고 싶다고 가정 해 봅시다. vanilla.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 문서를 확인하십시오 .


13

이것은 창문에서 저에게 효과적입니다.

# some_file.py on mainApp/app2 
import sys
sys.path.insert(0, sys.path[0]+'\\app2')

import some_file

10

나는 아주 특별하다 : 나는 Windows에서 파이썬을 사용한다!

나는 단지 정보를 완성합니다 : Windows와 Linux 모두에 대해 상대 경로와 절대 경로가 작동합니다 sys.path(여러 PC와 다른 기본 디렉토리에서 스크립트를 사용하기 때문에 상대 경로가 필요합니다).

및 Windows를 사용하는 경우 \/파일 이름을 구분 기호로 사용 될 수 있으며, 물론 당신이 두 배로해야한다 \파이썬 문자열에
몇 가지 유효한 예 :

sys.path.append('c:\\tools\\mydir')
sys.path.append('..\\mytools')
sys.path.append('c:/tools/mydir')
sys.path.append('../mytools')

(참고 : Linux 호환 가능하고 Windows 탐색기에 쓰고 복사하는 것이 더 간단하기 때문에 'Windows 네이티브'보다 적은 경우 이벤트 /보다 편리 하다고 생각합니다. \)


4
os.path.join ( 'tools', 'mydir')
Corey Goldberg

7

특정 경로에서 모듈을로드하는 목적이 사용자 정의 모듈을 개발하는 동안 도움이되는 경우 사용자 정의 모듈의 루트를 가리키는 테스트 스크립트의 동일한 폴더에 기호 링크를 작성할 수 있습니다. 이 모듈 참조는 해당 폴더에서 실행되는 스크립트에 대해 동일한 이름으로 설치된 다른 모듈보다 우선합니다.

나는 이것을 Linux에서 테스트했지만 심볼릭 링크를 지원하는 최신 OS에서 작동해야합니다.

이 접근 방식의 한 가지 장점은 자체 로컬 SVC 분기 작업 복사본에있는 모듈을 가리켜 개발주기 시간을 크게 단순화하고 다른 버전의 모듈을 관리하는 데 실패한 모드를 줄일 수 있다는 것입니다.


7

제 경우에는 반입 할 수업이있었습니다. 내 파일은 다음과 같습니다.

# /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

1
@ not2qubit sys를 답변으로 가져 오지 못했습니다.
Walter

7

나는 같은 질문에 여러 번 부딪 쳤으므로 솔루션을 공유하고 싶습니다.

파이썬 버전 : 3.X

다음 솔루션은 1 월 1 일 / 2020 이후 Python 2가 지원되지 않기 때문에 Python 버전 3.X에서 애플리케이션을 개발하는 사람을위한 솔루션입니다. .

프로젝트 구조

파이썬 3에서는 암시 적 네임 스페이스 패키지__init__.py 로 인해 프로젝트 서브 디렉토리에 필요하지 않습니다 . 참조 IS는 init로 평 파이썬 패키지에 필요하지 3.3 이상

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

행복한 코딩!



3

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/*'],
  },
)

매니페스트

recursive-include b *.*

/ init .py

from __future__ import absolute_import

from a.a import cats
import a.b

a / a.py

cats = 0

A / B / INIT

from __future__ import absolute_import

from a.b.b import dogs

a / b / b.py

dogs = 1

디렉토리에서 다음을 실행하여 모듈을 설치했습니다 MANIFEST.in.

python setup.py install

그런 다음 파일 시스템의 완전히 다른 위치에서 다음 /moustache/armwrestle을 실행할 수있었습니다.

import a
dir(a)

의도 한대로 실제로 a.cats0과 a.b.dogs같고 1 과 같음을 확인했습니다 .


2

그냥하는 대신 다음을 import ...수행하십시오.

from <MySubFolder> import <MyFile>

MyFile은 MySubFolder 안에 있습니다.


1

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


1

그래서 방금 IDE를 마우스 오른쪽 버튼으로 클릭하고 새 항목을 추가했으며 folder왜 가져올 수 없는지 궁금했습니다. 나중에 클래식 파일 시스템 폴더가 아닌 Python 패키지를 마우스 오른쪽 버튼으로 클릭하고 만들어야한다는 것을 깨달았습니다. 또는 __init__.py다른 답변에서 언급했듯이 사후 메소드는 (파이썬이 파일 시스템 폴더를 패키지로 취급하게 함)를 추가합니다 . 누군가가이 경로를 사용하는 경우를 대비하여 여기에이 답변을 추가하십시오.


1

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

import importlib

scriptName = 'Snake'

script = importlib.import_module('Scripts\\.%s' % scriptName)

이 예제에는 위 코드 인 main.py가 있고 Scripts라는 폴더가 있으며 scriptName변수 를 변경하여이 폴더에서 필요한 모든 것을 호출 할 수 있습니다 . 그런 다음 script이 모듈을 참조하는 데 사용할 수 있습니다 . Hello()Snake 모듈에서 호출 된 함수가있는 경우 다음과 같이하면 이 함수를 실행할 수 있습니다.

script.Hello()

파이썬 3.6에서 이것을 테스트했습니다.


0

이 문제가 여러 번 발생했습니다. 나는 같은 페이지에 많이왔다. 내 마지막 문제에서 나는server 에서 고정 디렉토리에서 했지만 디버깅 할 때마다 다른 하위 디렉토리에서 실행하려고했습니다.

import sys
sys.insert(1, /path) 

했어 NOT 때문에 다른 모듈에서 나를 위해 일을 내가 다른 읽을 수 있었다 *의 .CSV을 같은 디렉토리에있는 모든이었다 파일을.

결국, 나를 위해 일한 것은 pythonic이 아니라고 생각합니다.

나는 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')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.