서브 디렉토리에서 파일을 가져 오시겠습니까?


455

에있는이라는 파일이 tester.py있습니다 /project.

/project라는 하위 디렉토리가 lib있으며 다음과 같은 파일이 있습니다 BoxTime.py.

/project/tester.py
/project/lib/BoxTime.py

나는 가져올 BoxTime에서 tester. 나는 이것을 시도했다 :

import lib.BoxTime

결과 :

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

BoxTime하위 디렉토리에서 가져 오는 방법에 대한 아이디어가 있습니까?

편집하다

__init__.py문제 였지만을 참조하는 것을 잊지 마세요 BoxTimelib.BoxTime, 또는 사용 :

import lib.BoxTime as BT
...
BT.bt_function()

답변:


536

http://docs.python.org/tutorial/modules.html 여기에서 패키지 문서 (섹션 6.4)를보십시오.

요컨대, 당신은 이름이 빈 파일을 넣어야합니다

__init__.py

"lib"디렉토리에 있습니다.


59
해키 느낌 ? 파이썬이 안전하고 사용 가능한 가져 오기 디렉토리를 표시하는 방식입니다.
IAbstract

7
안전하고 사용 가능한 가져 오기 디렉토리를 표시 할뿐만 아니라 디렉토리 이름을 가져올 때 일부 초기화 코드를 실행하는 방법도 제공합니다.
Sadjad

32
예, 이것은 해킹적이고 심지어 더럽습니다. 제 생각에 언어는 파일 시스템에서 파일을로드하는 방법을 강요해서는 안됩니다. PHP에서 우리는 userland 코드가 네임 스페이스 / 클래스가 없을 때 호출되는 여러 자동 로딩 함수를 등록하게하여 문제를 해결했습니다. 그런 다음 커뮤니티는 PSR-4 표준을 작성했으며 Composer는이를 구현하므로 오늘날 아무도 그것에 대해 걱정할 필요가 없습니다. 그리고 바보 같은 하드 코딩 된 __init__파일은 없습니다 (그러나 원하는 경우 자동 로딩 후크를 등록하십시오! 이것은 해키해킹 가능 의 차이점입니다 ).
Morgan Touverey Quilling

4
@ AurélienOomsimport sys, os; sys.path.insert(0, os.path.abspath('..')); from sibling_package.hacks import HackyHackHack
jbowman

4
python은 지저분하다 :)
Jimmy Pettersson

174
  • 이라는 서브 디렉토리를 작성하십시오 lib.
  • 라는 빈 파일을 만듭니다 lib\__init__.py.
  • 에서 다음 과 같은 lib\BoxTime.py함수를 작성 foo()하십시오.

    def foo():
        print "foo!"
  • 위 디렉토리의 클라이언트 코드에서 다음을 lib작성하십시오.

    from lib import BoxTime
    BoxTime.foo()
  • 클라이언트 코드를 실행하십시오. 당신은 얻을 것이다 :

    foo!

훨씬 나중에-리눅스에서는 다음과 같이 보일 것입니다 :

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!

2
이것을 설명하는 파이썬 문서에 대한 링크를 제공 할 수 있습니까? 감사!
Zenon

5
링크를 클릭 가능하게 만드십시오 : docs.python.org/3/tutorial/modules.html#packages
Gabriel Staples

패키지 구현을위한 lib
MasterControlProgram

참고 : 하위 디렉토리에는 대시 또는 점이 포함되지 않지만 밑줄은 유효합니다. 나를 위해 다른 기호 이름과 동일한 제한 사항처럼 보이지만 아직 문서 수준으로 파고 들지 않았습니다.
Alexander Stohr

underscores => python3 (댓글을 편집하기에 너무 늦음)
Alexander Stohr

68

삽입 할 수 있습니다 sys.path:

sys.path.insert(0, './lib')
import BoxTime

11
어떤 이유로 init .py 파일을 만들 수 없거나 만들지 못하는 경우에 좋습니다 .
jpihl

1
"프로젝트"디렉토리에서 파이썬을 실행하면 작동합니다. "." 실행중인 파일이있는 디렉토리가 아닌 현재 작업 디렉토리를 기준으로 해석됩니다. 당신 말 cd /data, python ../project/tester.py. 그런 다음 작동하지 않습니다.
morningstar

2
이것은 나를 위해 일했습니다. init .py 파일 보다 이것을 선호 합니다. 더 깨끗한 import 문을 만듭니다.
Taylor Evanson 2016 년

5
이것은 훨씬 더 잘 작동하며 "올바른"솔루션입니다. init .py는 모듈이있는 자체 하위 폴더가있는 boto와 같은 패키지를 엉망으로 만듭니다.
Dave Dopson

1
@jpihl 적어도 __init__.py 라는 empy 파일을 만들어 해당 폴더에서 파이썬 가져 오기 모듈을 허용해야합니다. 나는 그 해결책을 시도했고 완벽하게 작동합니다 (v2.7.6).
m3nda

31

모든 사람들이 lib디렉토리 를 만들어야한다고 제안하기 때문에 이것을 작성하고 있습니다.

하위 디렉토리 이름을 지정할 필요가 없습니다 lib. anything입력 한 이름을 지정할 수 있습니다 __init__.py.

리눅스 쉘에서 다음 명령을 입력하면됩니다 :

$ touch anything/__init__.py 

이제 다음 구조를 갖습니다.

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

그럼 당신은 가져올 수 mylibmain.py같은 :

from anything import mylib 

mylib.myfun()

다음과 같이 함수와 클래스를 가져올 수도 있습니다.

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

내부에 배치 한 모든 변수 함수 또는 클래스 __init__.py에도 액세스 할 수 있습니다.

import anything

print(anything.myvar)

또는 이렇게 :

from anything import myvar

print(myvar)

내 폴더 구조는 utils\__init__.pyutils\myfile.py입니다. (유틸리티에는 두 파일이 모두 포함되어 있음) 이것이 가져 오려고하는 방법 from utils.myfile import myMethod입니다. 그러나 나는 얻는다 ModuleNotFoundError: No module named 'utils'. 무엇이 잘못 될 수 있습니까? 추신 : 나는 폴더 와 같은 수준 Django에 가져 오기를 시도하고 있습니다views.pyutils
Jagruti

모듈을 가져올 때 절대 경로를 사용하고 다음을 사용하여 프로그램을 실행할 수 있습니다.PYTHONPATH=. python path/to/program.py
nurettin

21

lib 디렉토리에 __init__.py파일이 있습니까?

파이썬은 __init__.py디렉토리가 모듈인지 확인하기 위해 사용 합니다.


16

시도하십시오 import .lib.BoxTime. 자세한 정보는 PEP 328의 상대 가져 오기에 대해 읽으십시오 .


2
이전에 사용 된 구문을 본 적이 없다고 생각합니다. 이 방법을 사용해야 할 강력한 이유가 있습니까?
tgray

2
이것이 왜 대답이 아닌가? 물론 전체 패키지 작업을 수행하려면 그렇게해야합니다. 그러나 그것은 원래의 질문이 아닙니다.
Travis Griggs

ValueError : 비 패키지에서 상대적 가져 오기 시도
Alex

5
가져 오는 파일이 패키지의 일부인 경우에만 작동합니다. 그렇지 않으면 @Alex가 지적한 오류가 표시됩니다.
Jonathon Reinhart

8

나는 기본적으로 모든 경우를 다루는이 작업을 수행합니다 ( __init__.py상대 / 경로 / to / your / lib / 폴더에 있는지 확인하십시오 ).

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


예 :
프로젝트 폴더에 있습니다.

/root/myproject/app.py

다른 프로젝트 폴더에 있습니다.

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

/root/anotherproject/utils.py그 안에있는 foo 함수 를 사용 하고 호출 하려고 합니다.

따라서 app.py로 작성하십시오.

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

2
사용하는 경우 경로 연결에서 '/'를 하드 코딩하는 대신 os.path사용하고 싶을 것입니다 os.path.join((os.path.dirname(os.path.realpath(__file__)),'..','anotherproject').
cowbert

"../anotherproject"없이는 할 수 os.path.dirname()없습니까?
Moshe Rabaev

@MosheRabaev-os.path 함수를 사용하는 것이 좋습니다. "../anotherproject"를 작성하고 코드를 Windows OS로 옮기는 경우 코드가 깨집니다! os.path utils는 코드가 실행되는 OS를 고려하여 올바른 경로를 반환하는 방법을 알고 있습니다. 자세한 내용은 docs.python.org/2/library/os.path.html
Mercury

@MosheRabaev 및를 사용하지 않고 ".."를 사용 dirname(realpath(__file__))하면 스크립트가 실행되는 위치가 아닌 스크립트를 실행할 때 현재 작업 디렉토리에 상대적인 경로를 계산합니다.
TJ Ellis

5

__init__.py서브 디렉토리 / lib에 빈 파일 을 작성하십시오 . 그리고 메인 코드의 시작 부분에 추가하십시오

from __future__ import absolute_import 

그때

import lib.BoxTime as BT
...
BT.bt_function()

또는 더 나은

from lib.BoxTime import bt_function
...
bt_function()

0

이 답변에 추가하십시오.

모든 서브 디렉토리 에서 모든 파일 을 가져 오려면 파일 의 루트에 추가하십시오.

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

그런 다음 파일이 현재 디렉토리 안에있는 것처럼 하위 디렉토리에서 파일을 간단히 가져올 수 있습니다.

작업 예

내 프로젝트에 하위 디렉토리가있는 다음 디렉토리가있는 경우 ...

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
   ├── d.py
   └── e.py
├── subdirectory_b
   └── f.py
├── subdirectory_c
   └── g.py
└── subdirectory_d
    └── h.py

a.py파일에 다음 코드를 넣을 수 있습니다

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

즉,이 코드는 파일이 어느 디렉토리에서 오는지 추상화합니다.


-1

/project/tester.py

/project/lib/BoxTime.py

파일에 __init__.py도달 할 때까지 빈 줄을 빈 줄로 만듭니다.

/project/lib/somefolder/BoxTime.py

#lib-2 개의 항목이 필요하고 __init__.pysomefolder라는 디렉토리 #somefolder에는 2 개의 항목이 boxtime.py있으며__init__.py


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