Python에서 순환 가져오기를 수정하는 다양한 방법
Python에서 순환 가져오기를 접해본 적이 있나요? 글쎄요, 디자인이나 구조에 문제가 있음을 나타내는 매우 일반적인 코드 냄새입니다.
순환 가져오기 예시
순환 가져오기는 어떻게 발생하나요? 이 가져오기 오류는 일반적으로 서로 의존하는 두 개 이상의 모듈이 완전히 초기화되기 전에 가져오려고 할 때 발생합니다.
module_1.py와 module_2.py라는 두 개의 모듈이 있다고 가정해 보겠습니다.
# module_1.py from module_2 import ModY class ModX: mody_obj = ModY()
# module_2.py from module_1 import ModX class ModY: modx_obj = ModX()
위 코드 조각에서 module_1과 module_2는 모두 서로 종속되어 있습니다.
mody_1의 mody_obj 초기화는 module_2에 따라 달라지며 module_2의 modx_obj 초기화는 module_1에 따라 다릅니다.
이것을 순환 종속성이라고 부릅니다. 두 모듈이 서로 로드를 시도하는 동안 가져오기 루프에 갇히게 됩니다.
module_1.py를 실행하면 다음과 같은 트레이스백을 얻게 됩니다.
Traceback (most recent call last): File "module_1.py", line 1, in <module> from module_2 import ModY File "module_2.py", line 1, in <module> from module_1 import ModX File "module_1.py", line 1, in <module> from module_2 import ModY ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
이 오류는 순환 가져오기 상황을 설명합니다. 프로그램이 module_2에서 ModY를 가져오려고 시도했을 때 module_2가 완전히 초기화되지 않았습니다(modX1에서 ModX를 가져오려고 시도하는 다른 가져오기 문으로 인해).
Python에서 순환 가져오기를 수정하는 방법은 무엇인가요? Python에서 순환 가져오기를 제거하는 방법에는 여러 가지가 있습니다.
Python에서 순환 가져오기 수정
코드를 공통 파일로 이동
가져오기 오류를 방지하기 위해 코드를 공통 파일로 이동한 다음 해당 파일에서 모듈을 가져올 수 있습니다.
# main.py ----> common file class ModX: pass class ModY: pass
위 코드 조각에서는 ModX 및 ModY 클래스를 공통 파일(main.py)로 이동했습니다.
# module_1.py from main import ModY class Mod_X: mody_obj = ModY()
# module_2.py from main import ModX class Mod_Y: modx_obj = ModX()
이제 module_1과 module_2는 순환 가져오기 상황을 수정하는 main에서 클래스를 가져옵니다.
이 접근 방식에는 문제가 있습니다. 때로는 코드베이스가 너무 커서 코드를 다른 파일로 옮기는 것이 위험해질 수 있습니다.
가져오기를 모듈 끝으로 이동
모듈 끝에서 import 문을 이동할 수 있습니다. 이렇게 하면 다른 모듈을 가져오기 전에 모듈을 완전히 초기화할 시간이 주어집니다.
# module_1.py class ModX: pass from module_2 import ModY class Mod_X: mody_obj = ModY()
# module_2.py class ModY: pass from module_1 import ModX
클래스/함수 범위 내에서 모듈 가져오기
클래스 또는 함수 범위 내에서 모듈을 가져오면 순환 가져오기를 피할 수 있습니다. 이를 통해 클래스나 함수가 호출될 때만 모듈을 가져올 수 있습니다. 메모리 사용을 최소화하려는 경우에 적합합니다.
# module_1.py class ModX: pass class Mod_X: from module_2 import ModY mody_obj = ModY()
# module_2.py class ModY: pass class Mod_Y: from module_1 import ModX modx_obj = ModX()
mod_1과 module_2의 Mod_X 및 Mod_Y 클래스 범위 내에서 import 문을 각각 이동했습니다.
module_1 또는 module_2를 실행하면 순환 가져오기 오류가 발생하지 않습니다. 하지만 이 접근 방식을 사용하면 클래스 범위 내에서만 클래스에 액세스할 수 있으므로 가져오기를 전역적으로 활용할 수 없습니다.
모듈 이름/별명 사용
모듈 이름이나 이와 같은 별칭을 사용하면 문제가 해결됩니다. 이를 통해 런타임까지 순환 종속성을 연기하여 두 모듈 모두 완전히 로드할 수 있습니다.
# module_1.py from module_2 import ModY class ModX: mody_obj = ModY()
# module_2.py from module_1 import ModX class ModY: modx_obj = ModX()
importlib 라이브러리 사용
importlib 라이브러리를 사용하여 모듈을 동적으로 가져올 수도 있습니다.
Traceback (most recent call last): File "module_1.py", line 1, in <module> from module_2 import ModY File "module_2.py", line 1, in <module> from module_1 import ModX File "module_1.py", line 1, in <module> from module_2 import ModY ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
# main.py ----> common file class ModX: pass class ModY: pass
Python 패키지의 순환 가져오기
일반적으로 순환 수입 동일 패키지 내의 모듈에서 가져옵니다. 복잡한 프로젝트에서는 패키지 내에 패키지가 포함되어 디렉토리 구조도 복잡합니다.
이러한 패키지와 하위 패키지에는 모듈에 더 쉽게 액세스할 수 있도록 __init__.py 파일이 포함되어 있습니다. 여기서 의도하지 않게 모듈 간에 순환 종속성이 발생하는 경우가 있습니다.
다음과 같은 디렉토리 구조를 가지고 있습니다.
# module_1.py from main import ModY class Mod_X: mody_obj = ModY()
mainpkg 패키지와 main.py 파일이 있습니다. mainpkg에는 modpkg_x와 modpkg_y라는 두 개의 하위 패키지가 있습니다.
modpkg_x 및 modpkg_y 내의 각 Python 파일은 다음과 같습니다.
mainpkg/modpkg_x/__init__.py
# module_2.py from main import ModX class Mod_Y: modx_obj = ModX()
이 파일은 module_1과 module_1_1에서 두 클래스(ModX 및 ModA)를 모두 가져옵니다.
mainpkg/modpkg_x/module_1.py
# module_1.py class ModX: pass from module_2 import ModY class Mod_X: mody_obj = ModY()
module_1은 module_2에서 ModY 클래스를 가져옵니다.
mainpkg/modpkg_x/module_1_1.py
# module_2.py class ModY: pass from module_1 import ModX
module_1_1은 아무것도 가져오지 않습니다. 어떤 모듈에도 종속되지 않습니다.
mainpkg/modpkg_y/__init__.py
# module_1.py class ModX: pass class Mod_X: from module_2 import ModY mody_obj = ModY()
이 파일은 module_2에서 ModY 클래스를 가져옵니다.
mainpkg/modpkg_y/module_2.py
# module_2.py class ModY: pass class Mod_Y: from module_1 import ModX modx_obj = ModX()
module_2는 module_1_1에서 ModA 클래스를 가져옵니다.
main.py 파일에는 다음 코드가 있습니다.
root_dir/main.py
# module_1.py import module_2 as m2 class ModX: def __init__(self): self.mody_obj = m2.ModY()
기본 파일은 module_2에서 ModY 클래스를 가져옵니다. 이 파일은 module_2에 종속됩니다.
여기서 가져오기 주기를 시각화하면 modpkg_x 및 modpkg_y 내의 __init__.py 파일을 무시하고 다음과 같이 보일 것입니다.
메인 파일이 module_2에 종속되고, module_1도 module_2에 종속되고, module_2는 module_1_1에 종속되는 것을 볼 수 있습니다. 수입주기가 없습니다.
하지만 모듈은 __init__.py 파일에 의존하므로 __init__.py 파일이 먼저 초기화되고 모듈을 다시 가져옵니다.
현재 수입 주기는 이렇습니다.
이로 인해 module_1_1은 가짜 종속성인 module_1에 종속됩니다.
이 경우 하위 패키지 __init__.py 파일을 비우고 별도의 __init__.py 파일을 사용하면 패키지 수준에서 가져오기를 중앙 집중화하여 도움이 될 수 있습니다.
# module_1.py from module_2 import ModY class ModX: mody_obj = ModY()
이 구조에서는 mainpkg 내에 또 다른 하위 패키지 subpkg를 추가했습니다.
mainpkg/subpkg/__init__.py
# module_2.py from module_1 import ModX class ModY: modx_obj = ModX()
이렇게 하면 내부 모듈을 단일 소스에서 가져올 수 있어 교차 가져오기의 필요성이 줄어듭니다.
이제 main.py 파일 내에서 import 문을 업데이트할 수 있습니다.
root_dir/main.py
Traceback (most recent call last): File "module_1.py", line 1, in <module> from module_2 import ModY File "module_2.py", line 1, in <module> from module_1 import ModX File "module_1.py", line 1, in <module> from module_2 import ModY ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
이는 동일한 패키지 내 모듈 간의 순환 종속성 문제를 해결합니다.
결론
Python의 순환 종속성 또는 가져오기는 코드의 심각한 재구성 및 리팩토링을 나타내는 코드 냄새입니다.
Python에서 순환 종속성을 피하기 위해 위에서 언급한 방법 중 하나를 시도해 볼 수 있습니다.
?이 기사가 마음에 든다면 관심을 가질 만한 다른 기사
✅예제를 사용한 Flask의 템플릿 상속
✅예제를 통한 exec()와 eval()의 차이점
✅파이썬에서 전역 키워드 사용 이해
✅Python 유형 힌트: 함수, 반환 값, 변수
✅함수 정의에 슬래시와 별표를 사용하는 이유
✅학습률은 ML 및 DL 모델에 어떤 영향을 미치나요?
지금은 이게 다입니다.
계속 코딩하세요✌✌.
위 내용은 Python에서 순환 가져오기를 수정하는 다양한 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Linux 터미널에서 Python 버전을 보려고 할 때 Linux 터미널에서 Python 버전을 볼 때 권한 문제에 대한 솔루션 ... Python을 입력하십시오 ...

Python의 Pandas 라이브러리를 사용할 때는 구조가 다른 두 데이터 프레임 사이에서 전체 열을 복사하는 방법이 일반적인 문제입니다. 두 개의 dats가 있다고 가정 해

10 시간 이내에 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법은 무엇입니까? 컴퓨터 초보자에게 프로그래밍 지식을 가르치는 데 10 시간 밖에 걸리지 않는다면 무엇을 가르치기로 선택 하시겠습니까?

Fiddlerevery Where를 사용할 때 Man-in-the-Middle Reading에 Fiddlereverywhere를 사용할 때 감지되는 방법 ...

정규 표현식은 프로그래밍의 패턴 일치 및 텍스트 조작을위한 강력한 도구이며 다양한 응용 프로그램에서 텍스트 처리의 효율성을 높입니다.

Uvicorn은 HTTP 요청을 어떻게 지속적으로 듣습니까? Uvicorn은 ASGI를 기반으로 한 가벼운 웹 서버입니다. 핵심 기능 중 하나는 HTTP 요청을 듣고 진행하는 것입니다 ...

이 기사는 Numpy, Pandas, Matplotlib, Scikit-Learn, Tensorflow, Django, Flask 및 요청과 같은 인기있는 Python 라이브러리에 대해 설명하고 과학 컴퓨팅, 데이터 분석, 시각화, 기계 학습, 웹 개발 및 H에서의 사용에 대해 자세히 설명합니다.

파이썬에서 문자열을 통해 객체를 동적으로 생성하고 메소드를 호출하는 방법은 무엇입니까? 특히 구성 또는 실행 해야하는 경우 일반적인 프로그래밍 요구 사항입니다.
