python 에서 import 학습 메모

7474 단어 importpython
머리말
python 모듈 에는 두 가지 조직 방식 이 있 습 니 다.하 나 는 단순 한 python 파일 입 니 다.파일 이름 은 모듈 이름 이 고 하 나 는 가방 입 니 다.가방 은 몇 개의 python 파일 을 포함 하 는 디 렉 터 리 입 니 다.디 렉 터 리 아래 에 파일__init__.py이 있어 야 합 니 다.이렇게 디 렉 터 리 이름 은 모듈 이름 이 고 가방 안의 python 파일 도 가방 이름 을 통 해 가 져 올 수 있 습 니 다.파일 이름 방식 import
import 문법
import 문법 은 두 가지 가 있 습 니 다.
1.직접 import 모듈

 import Module
 import Module as xx
2.모듈 import 대상(하위 모듈,클래스,함수,변수 등)

 from Module import Name
 from Module immport Name as yy
as 문법 은 대상 을 설정 하 는 데 사용 되 는 별명 입 니 다.import 는 대상 이름 을 현재 파일 의 이름 공간 에 도입 합 니 다.
다음 디 렉 터 리 구조 가 있다 고 가정 합 니 다.

├── A.py
└── pkg
 ├── B.py
 └── __init__.py
현재 디 렉 터 리 에서 아래 문장 은 모두 유효 하 다

import A 
import pkg
import pkg.B
from pkg import B
토론 을 간소화 하기 위해 서 는 as 문법 에 대해 예 를 들 지 않 을 것 이다.
import 절차
python 모든 불 러 온 모듈 정 보 는 sys.modules 구조 에 저 장 됩 니 다.import 모듈 이 있 을 때 다음 과 같은 절차 로 진 행 됩 니 다.
  • import A 라면sys.modules에 A 가 있 는 지,있 으 면 불 러 오지 않 고 없 으 면 A 에 module 대상 을 만 들 고 A
  • 를 불 러 옵 니 다.
  • from A import B 라면 A 를 위해 module 대상 을 만 든 다음 A 를 분석 하고 그 중에서 B 를 찾 아 A 로 채 우 는__dict__
  • 끼 워 넣 기 import
    import 모듈 에 있 을 때 우 리 는 한 모듈 이 import 에 여러 번 걸 리 지 않 을 까 걱정 할 수 있 습 니 다.A,B,C 세 개의 모듈 이 있다 고 가정 하면 A 는 import B 와 C,B 는 import C 가 필요 합 니 다.그러면 A 는 두 번 import C 로 실 행 됩 니 다.한 번 은 자신 자체 import 이 고 한 번 은 import B 에서 실 행 된 import 입 니 다.그러나 위 에서 말 한 import 절차 에 따 르 면 두 번 째 import 때 모듈 이 불 러 온 것 을 발 견 했 습 니 다.그래서 import 를 반복 하지 않 습 니 다.
    그러나 아래 와 같은 상황 은 오히려 잘못 보고 할 것 이다
    
    #filename: A.py
    from B import BB
    class AA:pass
    
    #filename: B.py
    from A import AA
    class BB:pass
    이 때 A.py 를 실행 하 든 B.py 를 실행 하 든 ImportError 의 이상 을 던 집 니 다.만약 에 우리 가 A.py 를 실행 했다 고 가정 하면 그 이 유 는 다음 과 같 습 니 다.
  • 파일 A.py 는 from B import BB 를 실행 합 니 다.B.py 를 먼저 스 캔 하 는 동시에 A 의 이름 공간 에서 B 에 게 module 대상 을 만 들 고 B 에서 BB
  • 를 찾 으 려 고 합 니 다.
  • B.py 첫 줄 을 스 캔 하여 실행from A import AA하 는데 이때 A.py
  • 를 스 캔 합 니 다.
  • 스 캔 A.py 첫 줄 실행from B import BB1 단계 가 B 에 게 module 대상 을 만 들 었 기 때문에 B 의 module 대상__dict__에서 BB 를 직접 얻 을 수 있 습 니 다.이때 BB 는 얻 을 수 없 음 이 분명 합 니 다.그래서 이상 을 던 집 니 다.
  • 이런 상황 을 해결 하 는 데 는 두 가지 방법 이 있다.
  • from B import BB 를 import B 로 변경 하거나 from A import AA 를 import A
  • 로 변경
  • A.py 또는 B.py 의 두 줄 코드 를 위 치 를 교환 합 니 다.
  • 한 마디 로 import 가 주의해 야 할 것 은 가능 한 한 사용 해 야 할 때 import 입 니 다.
    가방 import
    디 렉 터 리 아래__init__.py파일 이 있 을 때 이 디 렉 터 리 는 python 가방 입 니 다.
    import 패키지 와 import 단일 파일 은 같 습 니 다.우 리 는 이렇게 비교 할 수 있 습 니 다.
  • import 단일 파일 시 파일 의 클래스,함수,변 수 는 모두 import 의 대상
  • 이 될 수 있 습 니 다.
  • import 가방 시 가방 안의 하위 가방,파일,그리고__init__.py의 클래스,함수,변 수 는 모두 import 의 대상
  • 이 될 수 있 습 니 다.
    다음 디 렉 터 리 구조 가 있다 고 가정 합 니 다.
    
    pkg
    ├── __init__.py
    └── file.py
    그 중init__.py 내용 은 다음 과 같 습 니 다.
    
    argument = 0
    class A:pass
    pkg 와 같은 등급 의 디 렉 터 리 에서 다음 문 구 를 실행 하 는 것 은 모두 OK 입 니 다.
    
    >>> import pkg
    >>> import pkg.file
    >>> from pkg import file
    >>> from pkg import A
    >>> from pkg import argument
    그러나 다음 과 같은 문 구 는 잘못된 것 이다.
    
    >>> import pkg.A
    >>> import pkg.argument
    오류 보고ImportError: No module named xxx.왜냐하면 우리 가 실행import A.B할 때 A 와 B 는 모두 모듈(파일 이나 가방)이 어야 하기 때문이다.
    상대 가 져 오기 와 절대 가 져 오기
    절대 가 져 오 는 형식 은import A.B또는from A import B이 고,상대 가 져 오 는 형식 은from . import B또는from ..A import B입 니 다.현재 모듈 을 대표 합 니 다..상층 모듈 을 대표 합 니 다..상층 모듈 을 대표 하고,순서대로 유추 합 니 다.우리 가 여러 개의 가방 을 가지 고 있 을 때 하나의 가방 import 다른 가방 의 내용 을 필요 로 할 수 있 습 니 다.이것 은 절대적 으로 가 져 올 수 있 습 니 다.이것 은 흔히 오류 가 발생 하기 쉬 울 때 입 니까?아니면 구체 적 인 예 로 설명 합 니까?
    디 렉 터 리 구 조 는 다음 과 같다.
    
    app
    ├── __inti__.py
    ├── mod1
    │ ├── file1.py
    │ └── __init__.py
    ├── mod2
    │ ├── file2.py
    │ └── __init__.py
    └── start.py
    그 중app/start.py내용 은import mod1.file1 app/mod1/file1.py내용 은from ..mod2 import file2분석 하기 편리 하도록 우 리 는 모든 py 파일(4567914 포함)첫 줄 에 가입__init__.py현재print __file__, __name__에서 상대 적 인 가 져 오기 가 사용 되 었 습 니 다.저 희 는 app/mod 1 에서 실행app/mod1/file1.py하거나 app 에서 실행python file1.py하면 모두 잘못 보고 합 니 다python mod1/file1.py.
    app 에서 실행ValueError: Attempted relative import in non-package또는python -m mod1.file1모두 잘못 보고 합 니 다python start.py구체 적 인 원인 은 다음 에 다시 이야기 하 자.우 리 는 먼저 모듈 을 가 져 올 때의 규칙 들 을 살 펴 보 자.
    가방 구 조 를 명확 하 게 지정 하지 않 은 상태 에서 python 은name__가방 에 있 는 모듈 의 구 조 를 결정 합 니 다.만약main__그 자체 가 꼭대기 층 모듈 이 고 가방 구조 가 없 으 며 A.B.C 구조 라면 꼭대기 층 모듈 은 A 입 니 다.
    기본적으로 이런 원칙 을 따르다
  • 절대 가 져 오 면 한 모듈 은 자신의 하위 모듈 이나 최상 위 모듈 과 같은 등급 의 모듈 과 하위 모듈
  • 만 가 져 올 수 있 습 니 다.
  • 상대 적 으로 가 져 오 면 하나의 모듈 은 패키지 구조 가 있어 야 하고 꼭대기 모듈 내부 의 모듈 만 가 져 올 수 있 습 니 다.
  • 다음 과 같은 디 렉 터 리 구조 가 있 습 니 다.
    
    A
    ├── B1
    │ ├── C1
    │ │ └── file.py
    │ └── C2
    └── B2
    그 중에서 A,B1,B2,C1,C2 는 모두 가방 입 니 다.여 기 는 간단하게 열거 되 지 않 은ValueError: Attempted relative import beyond toplevel package파일 을 보 여주 기 위해 file.py 의 가방 구조 가 A.B1.C1.file(디스크 의 디 렉 터 리 구조 가 아 닌__init__.py에 따라 실 행 될 때 해당 하 는 가방 디 렉 터 리 구조 가 다 를 때__name__다음 과 같은 절대적 인 가 져 오기 가 가능 합 니 다.
    
    import A.B1.C2
    import A.B2
    다음 과 같은 상대 가 져 오기
    
    from .. import C2
    from ... import B2
    어떤 경우 file.py 의 가방 구 조 를 A.B1.C.file 로 만 들 수 있 습 니까?다음 과 같은 두 가지 가 있 습 니 다.
  • A 의 상위 디 렉 터 리 에서 실행file.py하 는데 이때 가방 구조
  • 를 명 확 히 지정 했다.
  • A 의 상층 디 렉 터 리 에 파일 start.py 를 만 들 고file.py에 import A.B1.C1.file 이 있 으 며 실행python -m A.B1.C1.file합 니 다.이때 가방 구 조 는start.pypython start.py변수 에 따라 이 루어 집 니 다.
  • 앞의 두 가지 상황 을 보면 첫 번 째 집행file.py__name__이다.이때python file1.pypython mod1/file1.pyfile.py이다.즉,그 자체 가 꼭대기 모듈 이 고 가방 구조 가 없 기 때문에 잘못 보고 할 수 있다.
    두 번 째 상황 은 실행__name____main__을 할 때 전 자 는 해석 기 mod1 이 꼭대기 층 모듈 이 고 후 자 는 file 1 을 가 져 와 야 하 며python -m mod1.file1python start.pyfile1.py이 고 꼭대기 층 모듈 도 mod1 이 므 로__name__에서 실행mod1.file1할 때 오류 가 발생 합 니 다.mod2 는 꼭대기 층 모듈 mod1 내부 에 있 지 않 기 때 문 입 니 다.오류 스 택 을 통 해 알 수 있 듯 이file1.py에서 타 임 스 오 류 를 절대적 으로 가 져 온 것 이 아니 라from ..mod2 import file2에서 상대 적 으로 가 져 온 신문 의 잘못 이다.
    그러면 어떻게 해야만 우연히 정확하게 실행 할 수 있 습 니까?두 가지 방법 이 있 습 니 다.하 나 는 app 상층 디 렉 터 리 에서 실행 하 는 것start.py이 고 다른 하 나 는 디 렉 터 리 구 조 를 바 꾸 어 모든 가방 을 큰 가방 에 넣 는 것 입 니 다.다음 과 같 습 니 다.
    
    app
    ├── pkg
    │ ├── __init__.py
    │ ├── mod1
    │ │ ├── __init__.py
    │ │ └── file1.py
    │ └── mod2
    │ ├── __init__.py
    │ └── file2.py
    └── start.py
    file1.py내용 을python -m app.mod1.file1로 바 꾸 고 app 에서 실행start.py총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 논문 의 내용 이 여러분 에 게 python 을 배우 거나 사용 하 는 데 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글 을 남 겨 주 십시오.

    좋은 웹페이지 즐겨찾기