웹상에 이러한 python
원형 질문이 여러 개 있습니다. Ray Hettinger가 순환 가져 오기의 유즈 케이스를 합법화하는 주석을 가지고 있기 때문에이 스레드에 기여하기로 결정했지만 가져 오기를 메소드로 이동하는 특히 좋은 연습은 아니라고 생각하는 솔루션을 권장합니다. 그렇다 Hettinger의 기관에서
는 일반적인 반대 세 면책 조항이 필요하다 :
- 는 내가 자바로 프로그램 된 적이 없습니다. Java 스타일을 시도하지 않습니다.
- 리팩토링이 항상 유용하거나 효과적인 것은 아닙니다.논리적 API는 때때로 반복적 인 import 참조를 피할 수 없도록 만드는 구조를 지시합니다. 프로그래머가 아닌 사용자를위한 코드가 있다는 것을 기억하십시오.
- 상당히 큰 모듈을 결합하면 가독성 및 유지 관리 문제가 발생할 수 있습니다.이 문제는 하나 또는 두 개의 재귀 수입보다 훨씬 나쁠 수 있습니다. 또한
, 나는, 유지 보수성 및 가독성이 수입이 파일의 상단에 분류 할 것을 지시 생각 각각의 필요에 이름을 한 번만 발생하고, from module import name
스타일은 매우 짧은 모듈 이름을 아마 제외 (바람직하다 반복적 인 언어 적 혼란을 피하고 종속성을 명시 적으로 만들어주기 때문에 많은 기능 (예 : gtk
)이 필요합니다.
그런 식으로 나에게 가져온 내 자신의 유스 케이스의 단순화 된 버전을 제시하고 해결책을 제시 할 것입니다.
나는 두 개의 모듈을 가지고 있는데, 각각은 많은 클래스를 정의한다. surface
은 평면, 구, 쌍곡면과 같은 기하학적 인면을 정의합니다. path
은 선, 원의 쌍곡선 등과 같은 평면 기하학적 수치를 논리적으로 정의합니다. 이들은 논리적으로 별개의 범주이며 API 요구 사항의 관점에서 볼 때 리팩토링은 옵션이 아닙니다. 그럼에도 불구하고이 두 범주는 친밀합니다.
유용한 작업은 두 개의면을 교차시킵니다. 예를 들어 두면의 교차가 선이거나 평면과 구의 교차가 원입니다. 예를 들어, surface.py
에 교차로 작업에 대한 반환 값을 구현하는 데 필요한 똑바로 앞으로 수입 할 경우
:
from path import Line
를 당신이 얻을 :
Traceback (most recent call last):
File "surface.py", line 62, in <module>
from path import Line
File ".../path.py", line 25, in <module>
from surface import Plane
File ".../surface.py", line 62, in <module>
from path import Line
ImportError: cannot import name Line
을 기하학적으로, 비행기는 데 사용됩니다 결국 경로를 정의하면 3 가지 (또는 그 이상) 차원에서 임의로 방향을 지정할 수 있습니다. 추적 표시는 현재 일어나고있는 일과 해결 방법을 알려줍니다. 추적이 다시 여전히 일어나고에
try: from path import Line
except ImportError: pass # skip circular import second pass
작업의 순서 :
는 간단히과 surface.py
에 import 문을 교체합니다. 두 번째로 가져 오기 실패를 무시합니다. 이는 모듈 수준에서 Line
이 사용되지 않았으므로 중요하지 않습니다. 따라서 필요한 네임 스페이스 surface
이 path
에로드됩니다. 따라서 path
의 네임 스페이스 구문 분석을 완료하여 surface
에로드하고 from path import Line
으로 첫 번째 만남을 완료 할 수 있습니다. 따라서 surface
의 네임 스페이스 구문 분석은 계속 진행될 수 있으며 필요한 다른 작업을 계속할 수 있습니다.
쉽고 명확한 관용어입니다. try: ... except ...
구문은 순환 수입 문제를 명확하고 간결하게 문서화하여 향후 유지 보수가 필요할 때마다 완화합니다. 리펙터가 실제로 나쁜 생각 일 때마다 사용하십시오.
좋은 디자인을 위해 원형 가져 오기를 제거 할 필요는 없습니다. 가져 오기를 메소드 정의로 이동하면 가져 오기를 연기하는 것이 합리적입니다. –