import 문은 항상 모듈 상단에 있어야합니까?


403

PEP 08 상태 :

가져 오기는 항상 파일의 맨 위에, 모듈 주석 및 문서 문자열 바로 다음과 모듈 전역 및 상수 바로 앞에 배치됩니다.

그러나 가져 오는 클래스 / 메서드 / 함수가 드문 경우에만 사용되는 경우, 필요할 때 가져 오기를 수행하는 것이 더 효율적입니까?

그렇지 않습니까?

class SomeClass(object):

    def not_often_called(self)
        from datetime import datetime
        self.datetime = datetime.now()

이보다 더 효율적입니까?

from datetime import datetime

class SomeClass(object):

    def not_often_called(self)
        self.datetime = datetime.now()

답변:


283

모듈 가져 오기는 매우 빠르지 만 즉각적인 것은 아닙니다. 이것은 다음을 의미합니다.

  • 수입은 모듈 상단에 두는 것이 좋습니다. 한 번만 지불하는 사소한 비용이기 때문입니다.
  • 함수 내에 가져 오기를 넣으면 해당 함수에 대한 호출이 더 오래 걸립니다.

따라서 효율성에 관심이 있다면 수입품을 맨 위에 놓으십시오. 프로파일 링에 도움이 될 것으로 보이는 경우에만 함수로 이동하십시오 ( 성능을 향상시키는 가장 좋은 곳을 프로파일하기 위해 프로파일 했습니까 ?)


게으른 가져 오기를 수행하는 가장 좋은 이유는 다음과 같습니다.

  • 선택적 라이브러리 지원. 코드에 다른 라이브러리를 사용하는 여러 경로가있는 경우 선택적 라이브러리가 설치되지 않은 경우 중단하지 마십시오.
  • 에서 __init__.py수입하지만, 실제로 사용되지 않을 수있는 플러그인의. 예를 들어 bzrlibLazy-loading 프레임 워크 를 사용하는 Bazaar 플러그인이 있습니다 .

17
John, 이것은 완전히 이론적 인 질문이므로 프로파일 링 할 코드가 없었습니다. 과거에는 항상 PEP를 따랐지만 오늘 올바른 코드인지 궁금해하는 코드를 작성했습니다. 당신의 도움을 주셔서 감사합니다.
Adam J. Forster

43
> 함수 내에서 가져 오기를 넣으면 해당 함수를 호출하는 데 시간이 오래 걸립니다. 실제로이 비용은 한 번만 지불한다고 생각합니다. 파이썬은 가져온 모듈을 캐시하여 다시 가져 오기위한 최소한의 비용 만 가짐을 읽었습니다.
meltform

24
@halfhourhacks 파이썬은 모듈을 가져올 재하지 않습니다,하지만 여전히 / 모듈이 존재하는 경우 단지 확인하기 위해 몇 가지 지침을 수행해야하는 등 sys.modules에 /에
존 밀리 킨

24
-1. 함수에 가져 오기를한다고해서 시간이 더 걸리는 것은 아닙니다. 다른 질문에 대한 내 답변 을 참조하십시오 .
aaronasterling

4
한 가지 사용 사례는 순환 수입을 피하는 것입니다 (보통 현명하지는 않지만 때로는 적합 함). 때때로 모듈 m1의 클래스 A는 클래스 A의 다른 인스턴스를 구성하는 모듈 m2의 클래스 B에서 메소드를 호출합니다. 클래스 A의 인스턴스를 구성하는 클래스 B의 메소드가 인스턴스를 구성하는 함수를 실행할 때만 가져 오기가 실행되는 경우, 원형 가져 오기는 피합니다.
Sam Svenbjorgchristiensensen

80

import 문을 함수 안에 넣으면 순환 종속성을 막을 수 있습니다. 예를 들어, X.py와 Y.py라는 두 개의 모듈이 있고 두 모듈이 서로를 가져와야하는 경우 무한 루프를 일으키는 모듈 중 하나를 가져올 때 순환 종속성이 발생합니다. 모듈 중 하나에서 import 문을 이동하면 함수가 호출 될 때까지 다른 모듈을 가져 오려고 시도하지 않으며 해당 모듈을 이미 가져 오기 때문에 무한 루프가 없습니다. 자세한 내용은 여기를 참조하십시오 -effbot.org/zone/import-confusion.htm


3
그렇습니다.하지만 의존성 지옥에 빠질 수 있습니다.
eigenein

8
두 모듈이 서로를 가져와야하는 경우 코드에 심각한 문제가 있습니다.
Anna

객체 지향 프로그래밍은 종종 순환 종속성으로 이어집니다. 중요한 객체 클래스를 여러 모듈로 가져올 수 있습니다. 이 객체가 자체 작업을 수행하려면 하나 이상의 해당 모듈에 접근해야합니다. 다른 모듈에 액세스 할 수 있도록 함수 인수를 통해 객체에 데이터를 보내는 등의 방법을 피할 수 있습니다. 그러나이 작업을 수행하는 것이 OOP에 반 직관적으로 느껴질 때가 있습니다 (외부 세계는 해당 기능에서 작업을 수행하는 방법을 알 필요가 없습니다).
Robert

4
X가 Y를 필요로하고 Y가 X를 필요로 할 때, 그것들은 같은 아이디어의 두 부분이거나 (즉, 함께 정의되어야 함) 누락 된 추상화가 있습니다.
GLRoman

59

모듈의 맨 위가 아닌 모든 임포트를 사용하는 함수에 모든 임포트를 배치하는 관행을 채택했습니다.

내가 얻는 이점은보다 안정적으로 리팩토링 할 수 있다는 것입니다. 한 모듈에서 다른 모듈로 함수를 옮길 때, 그 함수는 기존의 모든 테스트에서 그대로 작동한다는 것을 알고 있습니다. 모듈 상단에 가져 오기가 있으면 함수를 이동할 때 새 모듈 가져 오기를 완료하고 최소화하는 데 많은 시간이 소요됩니다. 리팩토링 IDE는 이것을 무의미하게 만들 수 있습니다.

다른 곳에서 언급 한 바와 같이 속도 불이익이 있습니다. 내 응용 프로그램에서 이것을 측정했으며 내 목적에 중요하지 않은 것으로 나타났습니다.

검색에 의존하지 않고 모든 모듈 종속성을 미리 볼 수 있다는 것도 좋습니다 (예 : grep). 그러나 모듈 종속성에 관심이있는 이유는 일반적으로 단일 모듈뿐만 아니라 여러 파일로 구성된 전체 시스템을 설치, 리팩토링 또는 이동하기 때문입니다. 이 경우 어쨌든 시스템 수준의 종속성을 갖도록 전역 검색을 수행 할 것입니다. 따라서 실제로 시스템에 대한 이해를 돕기 위해 전 세계 수입품을 찾지 못했습니다.

나는 보통의 가져 오기를 넣어 sys내부를 if __name__=='__main__'확인하고 (같은 인수를 전달 sys.argv[1:]A를) main()기능. 이를 통해 가져 오지 않은 main컨텍스트에서 사용할 수 있습니다 sys.


4
많은 IDE는 필요한 모듈을 파일에 최적화하고 자동으로 가져와 코드 리팩토링을 쉽게합니다. 대부분의 경우 PyCharm과 Eclipse는 나를 위해 올바른 결정을 내 렸습니다. emacs 또는 vim에서 동일한 동작을 얻는 방법이있을 것입니다.
brent.payne

3
전역 네임 스페이스의 if 문 내에서 가져 오기는 여전히 전역 가져 오기입니다. 그러면 인수가 인쇄됩니다 (Python 3 사용). 새로운 네임 스페이스를 만들려면 함수를 def main(): print(sys.argv); if True: import sys; main();래핑해야 if __name__=='__main__'합니다.
Darcinon

4
이것은 전역 범위가 아닌 함수 내에서 가져 오기 위한 훌륭한 이유입니다. 나는 같은 이유로 다른 사람이 언급하지 않은 것에 놀랐습니다. 성능 및 상세 성 외에 중요한 단점이 있습니까?
algal

@algal 단점은 많은 파이썬 사람들이 pep 코덱을 위반하기 때문에 이것을 싫어한다는 것입니다. 팀원을 설득해야합니다. 성능 저하가 최소화됩니다. 때로는 더 빠릅니다. stackoverflow.com/a/4789963/362951
mit

수입품을 내가 사용하는 곳 가까이에 두는 것이 리팩토링에 매우 유용하다는 것을 알았습니다. 더 이상 많은 팀의 상단과 후면으로 스크롤 할 필요가 없습니다. 나는 pycharm 또는 wing ide와 같은 IDE를 사용하고 리팩토링도 사용하지만 항상 의존하지는 않습니다. 이 대체 가져 오기 스타일을 사용하면 함수를 다른 모듈로 이동하는 것이 훨씬 쉬워집니다.
mit

39

대부분의 경우 이것은 명확하고 현명한 작업에 유용하지만 항상 그런 것은 아닙니다. 다음은 모듈 가져 오기가 다른 곳에있을 수있는 몇 가지 상황의 예입니다.

먼저 다음과 같은 형식의 단위 테스트가있는 모듈을 가질 수 있습니다.

if __name__ == '__main__':
    import foo
    aa = foo.xyz()         # initiate something for the test

둘째, 런타임에 다른 모듈을 조건부로 가져와야 할 수도 있습니다.

if [condition]:
    import foo as plugin_api
else:
    import bar as plugin_api
xx = plugin_api.Plugin()
[...]

코드의 다른 부분으로 가져 오기를 수행 할 수있는 다른 상황이있을 수 있습니다.


14

함수가 0 번 또는 1 번 호출 될 때 첫 번째 변형이 실제로 두 번째 변형보다 더 효율적입니다. 그러나 두 번째 및 후속 호출에서는 "모든 통화 가져 오기"방식이 실제로 덜 효율적입니다. "lazy import"를 수행하여 두 가지 방법 중 최고를 결합한 lazy-loading 기술에 대해서는 이 링크 를 참조하십시오 .

그러나 효율성 이외의 다른 이유가 있습니다. 한 가지 접근 방식은이 모듈의 종속성에 대한 코드를 읽는 사람에게 훨씬 더 명확합니다. 또한 실패 특성이 매우 다릅니다. 첫 번째는 "datetime"모듈이 없으면로드시 실패하고, 두 번째는 메소드가 호출 될 때까지 실패하지 않습니다.

추가 된 참고 : IronPython에서 가져 오기는 코드가 기본적으로 컴파일 될 때 컴파일되므로 CPython보다 가져 오기 비용이 약간 더 비쌉니다.


1
그것은 사실이 아니다 그 첫 번째 수행 더 나은 : wiki.python.org/moin/PythonSpeed/...
제이슨 베이커

가져 오기가 발생하지 않기 때문에 메소드가 호출되지 않으면 더 잘 수행됩니다.
Curt Hagenlocher

사실이지만 메소드가 두 번 이상 호출되면 성능이 저하됩니다. 그리고 모듈을 즉시 가져 오지 않으면 얻을 수있는 성능 이점은 대부분 무시할 수 있습니다. 모듈이 매우 크거나 이러한 종류의 기능이 많은 경우는 예외입니다.
Jason Baker

IronPython 세계에서 초기 수입은 CPython보다 훨씬 비쌉니다. 링크의 "게으른 가져 오기"예제는 아마도 가장 일반적인 전체 솔루션 일 것입니다.
Curt Hagenlocher

나는 당신이 마음에 들지 않기를 희망하지만 당신의 게시물로 편집했습니다. 유용한 정보입니다.
Jason Baker

9

Curt는 좋은 지적을합니다. 두 번째 버전은 더 명확하고 나중에로드 타임에 예기치 않게 실패합니다.

일반적으로 모듈 로딩의 효율성에 대해 걱정하지 않습니다. 모듈은 (a) 매우 빠르며 (b) 대부분 시작시에만 발생하기 때문입니다.

예기치 않은 시간에 헤비급 모듈을로드해야하는 경우, 그것은 아마로 동적으로로드하는 것이 더 의미가 __import__기능, 수 있는지 캐치에 ImportError예외 및 합리적인 방식으로 그들을 처리 할 수 있습니다.


8

모듈을 너무 많이로드하는 효율성에 대해 걱정하지 않습니다. 모듈이 차지하는 메모리는 충분히 크지 않으며 (모듈식이라고 가정) 시작 비용은 무시할 수 있습니다.

대부분의 경우 소스 파일 맨 위에 모듈을로드하려고합니다. 코드를 읽는 사람에게는 어떤 모듈에서 어떤 기능이나 객체가 왔는지 훨씬 쉽게 알 수 있습니다.

코드의 다른 곳에서 모듈을 가져 오는 좋은 이유 중 하나는 디버깅 문에서 모듈을 사용하는 것입니다.

예를 들면 다음과 같습니다.

do_something_with_x(x)

나는 이것을 디버깅 할 수있다 :

from pprint import pprint
pprint(x)
do_something_with_x(x)

물론 코드의 다른 곳에서 모듈을 가져 오는 다른 이유는 모듈을 동적으로 가져와야하기 때문입니다. 선택의 여지가 거의 없기 때문입니다.

모듈을 너무 많이로드하는 효율성에 대해 걱정하지 않습니다. 모듈이 차지하는 메모리는 충분히 크지 않으며 (모듈식이라고 가정) 시작 비용은 무시할 수 있습니다.


우리는 (컴퓨터에서) 모듈 당 수십 밀리 초의 시작 비용에 대해 이야기하고 있습니다. 예를 들어 웹 애플리케이션이 사용자 클릭에 응답하는 데 영향을 미치는 경우 항상 무시할 수있는 것은 아닙니다.
Evgeni Sergeev

6

프로그래머 만 결정할 수있는 것은 트레이드 오프입니다.

사례 1은 필요할 때까지 datetime 모듈을 가져 오지 않고 (필요한 초기화 수행) 메모리와 시작 시간을 절약합니다. '호출 될 때만'가져 오기는 '호출 될 때마다'수행하는 것을 의미하므로 첫 번째 호출 이후의 각 호출은 여전히 ​​가져 오기를 수행하는 추가 오버 헤드가 발생합니다.

이 경우 사전에 그렇게 (not_often_called 것을 날짜를 가져 와서 약간의 실행 시간과 대기 시간 절약 사례 2) 더 빨리 돌아갑니다 이다 모든 통화에 발생하는 수입의 오버 헤드를하지 않음으로써라고도합니다.

효율성 외에도, import 문이 ... 앞에 있으면 모듈 종속성을 쉽게 볼 수 있습니다. 코드에 그것들을 숨기면 어떤 모듈이 의존하는지 쉽게 찾기가 어려울 수 있습니다.

개인적으로 나는 단위 테스트와 같은 것을 제외하고 일반적으로 PEP를 따르며 테스트 코드를 제외하고는 사용되지 않을 것이라는 것을 알고 있기 때문에 항상로드하고 싶지 않습니다.


2
-1. 가져 오기의 주요 오버 헤드는 처음에만 발생합니다. 모듈을 찾는 데 드는 비용은 sys.modules전체 이름 대신 로컬 이름을 검색하기 만하면 절약되므로 쉽게 상쇄 할 수 있습니다.
aaronasterling

6

다음은 모든 가져 오기가 맨 위에있는 예입니다 (이 작업을 수행해야하는 유일한 시간 임). Un * x와 Windows에서 하위 프로세스를 종료하고 싶습니다.

import os
# ...
try:
    kill = os.kill  # will raise AttributeError on Windows
    from signal import SIGTERM
    def terminate(process):
        kill(process.pid, SIGTERM)
except (AttributeError, ImportError):
    try:
        from win32api import TerminateProcess  # use win32api if available
        def terminate(process):
            TerminateProcess(int(process._handle), -1)
    except ImportError:
        def terminate(process):
            raise NotImplementedError  # define a dummy function

(리뷰에서 : John Millikin이 말한 것.)


6

이것은 다른 많은 최적화와 마찬가지로 속도에 대한 가독성을 희생합니다. 존은 당신이 당신의 프로파일 링 숙제를 한 경우, 언급 발견이 상당히 유용 충분히 변화 될 수 다음 다시 가서, 여분의 속도가 필요합니다. 다른 모든 수입품과 함께 메모를 작성하는 것이 좋습니다.

from foo import bar
from baz import qux
# Note: datetime is imported in SomeClass below

4

모듈 초기화는 처음 가져올 때 한 번만 발생합니다. 문제의 모듈이 표준 라이브러리에서 가져온 경우 프로그램의 다른 모듈에서도 가져올 수 있습니다. datetime만큼 널리 사용되는 모듈의 경우 다른 표준 라이브러리에 대한 종속성 일 수도 있습니다. 모듈 초기화가 이미 수행되었으므로 import 문은 비용이 거의 들지 않습니다. 이 시점에서 수행하는 모든 작업은 기존 모듈 객체를 로컬 범위에 바인딩하는 것입니다.

그 정보를 가독성에 대한 인수와 결합하면 모듈 범위에서 import 문을 갖는 것이 가장 좋습니다.


4

Moe의 답변 을 완성하기 위해 과 원래 질문 하십시오.

순환 의존성을 다루어야 할 때 몇 가지 "트릭"을 할 수 있습니다. 우리가 모듈로 작업하는 가정 a.pyb.py포함 그 x()와 b y()는 각각. 그때:

  1. 우리는 from imports모듈의 하단에서 하나를 움직일 수 있습니다 .
  2. from imports실제로 가져 오기가 필요한 함수 또는 메소드 내부를 이동할 수 있습니다 (여러 위치에서 사용할 수 있으므로 항상 가능하지는 않습니다).
  3. 둘 중 하나 from imports를 다음과 같은 가져 오기로 변경할 수 있습니다 .import a

결론을 내립니다. 순환 의존성을 다루지 않고 피할 수있는 트릭을 수행하는 경우이 질문에 대한 다른 답변에서 이미 설명 한 이유 때문에 모든 수입품을 맨 위에 두는 것이 좋습니다. 그리고이 "트릭"을 할 때 의견을 포함하십시오, 그것은 언제나 환영합니다! :)


4

이미 주어진 훌륭한 답변 외에도 수입품의 배치는 단순한 스타일의 문제가 아니라는 점에 주목할 가치가 있습니다. 때때로 모듈은 먼저 가져 오거나 초기화해야하는 암시 적 종속성을 가지고 있으며 최상위 가져 오기는 필요한 실행 순서를 위반할 수 있습니다.

이 문제는 종종 Apache Spark의 Python API에서 발생하며, 여기서 pyspark 패키지 또는 모듈을 가져 오기 전에 SparkContext를 초기화해야합니다. pyspark 가져 오기를 SparkContext가 사용 가능한 범위 내에서 배치하는 것이 가장 좋습니다.


4

예상되는 것에 대한 많은 좋은 설명이 있지만 이미 게시 된 반복 된로드 점검에 대한 실제 비용 번호를 보지 못한 것에 놀랐습니다.

상단에서 가져 오면 무엇이든로드 히트를 가져옵니다. 꽤 작지만 일반적으로 나노초가 아닌 밀리 초입니다.

당신이 함수 (들) 내에서 가져 오는 경우에, 당신은 단지로드의 타격을 하는 경우 그 기능 중 하나가 처음이라고합니다. 많은 사람들이 지적했듯이 전혀 발생하지 않으면로드 시간을 절약 할 수 있습니다. 기능 (들)을 많이 호출되는 경우에, 당신은이 (가 있음을 확인하기 위해 훨씬 더 작은 히트 불구하고 반복 가지고 있다 ; 실제로하지 재 로딩을로드). 반면에 @aaronasterling이 지적했듯이 함수 내에서 가져 오기하면 함수가 조금 더 빠른 로컬 변수 조회를 사용하여 나중에 이름을 식별 할 수 있기 때문에 약간의 절약도 가능합니다 ( http://stackoverflow.com/questions/477096/python- import-coding-style / 4789963 # 4789963 ).

다음은 함수 내부에서 몇 가지 항목을 가져 오는 간단한 테스트 결과입니다. 보고 된 시간 (2.3 GHz Intel Core i7의 Python 2.7.14에서)은 다음과 같습니다 (나중에 전화를 많이받는 두 번째 전화는 일관된 것처럼 보이지만 그 이유는 모르겠습니다).

 0 foo:   14429.0924 µs
 1 foo:      63.8962 µs
 2 foo:      10.0136 µs
 3 foo:       7.1526 µs
 4 foo:       7.8678 µs
 0 bar:       9.0599 µs
 1 bar:       6.9141 µs
 2 bar:       7.1526 µs
 3 bar:       7.8678 µs
 4 bar:       7.1526 µs

코드:

from __future__ import print_function
from time import time

def foo():
    import collections
    import re
    import string
    import math
    import subprocess
    return

def bar():
    import collections
    import re
    import string
    import math
    import subprocess
    return

t0 = time()
for i in xrange(5):
    foo()
    t1 = time()
    print("    %2d foo: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
    t0 = t1
for i in xrange(5):
    bar()
    t1 = time()
    print("    %2d bar: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
    t0 = t1

런타임의 변경은로드에 대한 CPU 주파수 스케일링으로 인한 것 같습니다. CPU 클럭 속도를 높이려면 바쁜 작업으로 속도 테스트를 시작하는 것이 좋습니다.
한광 니 엔 후이

3

다른 사람들이 이미이 작업을 잘 수행했기 때문에 완전한 답변을 제공하고자하지 않습니다. 함수 내에서 모듈을 가져 오는 데 특히 유용한 경우 하나의 유스 케이스를 언급하고 싶습니다. 내 응용 프로그램은 특정 위치에 저장된 python 패키지 및 모듈을 플러그인으로 사용합니다. 응용 프로그램을 시작하는 동안 응용 프로그램은 해당 위치의 모든 모듈을 살펴보고 가져옵니다. 그런 다음 모듈 내부를 살펴보고 플러그인의 일부 마운트 지점을 찾으면 (내 경우에는 고유 한 특정 기본 클래스의 하위 클래스입니다) ID) 등록합니다. 플러그인의 수는 많으며 (현재 수십 개, 향후 수백 개) 플러그인은 거의 사용되지 않습니다. 플러그인 모듈 상단에 타사 라이브러리를 가져 오는 것은 응용 프로그램 시작 중에 약간의 패널티였습니다. 특히 일부 타사 라이브러리는 가져 오기가 무겁습니다 (예 : 음반 가져 오기는 인터넷에 연결하여 시작하는 데 약 1 초가 추가 된 항목을 다운로드하려고 시도) 플러그인에서 가져 오기를 최적화하여 (사용되는 기능에서만 호출) 시작을 10 초에서 2 초로 줄였습니다. 그것은 내 사용자에게 큰 차이입니다.

내 대답은 아니요, 항상 수입품을 모듈 상단에 두는 것은 아닙니다.


3

직렬화 된 함수 코드가 다른 코어로 푸시 될 때 (예 : ipyparallel의 경우) 가져 오기가 함수에 있어야 할 필요가있는 병렬 처리에 대한 단일 답변이 지금까지 언급되지 않았다는 것이 흥미 롭습니다.


1

함수 내에서 변수 / 로컬 범위를 가져 오면 성능이 향상 될 수 있습니다. 이것은 함수 내에서 가져온 것들의 사용법에 달려 있습니다. 여러 번 반복하고 모듈 전역 객체에 액세스하는 경우 로컬로 가져 오면 도움이 될 수 있습니다.

test.py

X=10
Y=11
Z=12
def add(i):
  i = i + 10

runlocal.py

from test import add, X, Y, Z

    def callme():
      x=X
      y=Y
      z=Z
      ladd=add 
      for i  in range(100000000):
        ladd(i)
        x+y+z

    callme()

run.py

from test import add, X, Y, Z

def callme():
  for i in range(100000000):
    add(i)
    X+Y+Z

callme()

리눅스에서의 시간은 약간의 이익을 보여줍니다

/usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python run.py 
    0:17.80 real,   17.77 user, 0.01 sys
/tmp/test$ /usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python runlocal.py 
    0:14.23 real,   14.22 user, 0.01 sys

진짜는 벽시계입니다. 사용자는 프로그램 시간입니다. sys는 시스템 호출 시간입니다.

https://docs.python.org/3.5/reference/executionmodel.html#resolution-of-names


1

가독성

시작 성능 외에도 import명령문 을 현지화하기 위해 가독성 인수가 작성됩니다. 예를 들어 현재 첫 번째 python 프로젝트에서 python 줄 번호 1283에서 1296을 가져옵니다.

listdata.append(['tk font version', font_version])
listdata.append(['Gtk version', str(Gtk.get_major_version())+"."+
                 str(Gtk.get_minor_version())+"."+
                 str(Gtk.get_micro_version())])

import xml.etree.ElementTree as ET

xmltree = ET.parse('/usr/share/gnome/gnome-version.xml')
xmlroot = xmltree.getroot()
result = []
for child in xmlroot:
    result.append(child.text)
listdata.append(['Gnome version', result[0]+"."+result[1]+"."+
                 result[2]+" "+result[3]])

import문이 파일의 맨 위에 있으면 먼 길을 스크롤하거나을 눌러 Home내용 ET을 확인해야합니다. 그런 다음 코드를 계속 읽으려면 1283 행으로 다시 이동해야합니다.

실제로 import명령문이 함수 (또는 클래스)의 최상위 위치에 있더라도 호출 및 페이징이 필요합니다.

그놈 버전 번호 표시는 거의 수행되지 않으므로 import파일 맨 위에 불필요한 시작 지연이 발생합니다.


0

@John Millikin 및 @VK에서 언급 한 것과 매우 유사한 유스 케이스를 언급하고 싶습니다.

선택적 수입품

Jupyter Notebook을 사용하여 데이터 분석을 수행하고 모든 분석의 템플릿으로 동일한 IPython 노트북을 사용합니다. 어떤 경우에는 빠른 모델 실행을 위해 Tensorflow를 가져와야하지만 때로는 tensorflow가 설정되지 않았거나 가져 오기가 느린 곳에서 일하기도합니다. 이 경우 도우미 함수에서 Tensorflow 종속 작업을 캡슐화하고 해당 함수 내에서 tensorflow를 가져 와서 버튼에 바인딩합니다.

이런 식으로 가져 오기를 기다리거나 실패한 나머지 셀을 다시 시작하지 않고도 "다시 시작 및 실행"을 수행 할 수 있습니다.


0

이것은 흥미로운 토론입니다. 다른 많은 사람들처럼이 주제도 고려한 적이 없습니다. 내 라이브러리 중 하나에서 Django ORM을 사용하고 싶기 때문에 함수에서 가져 오기가 필요했습니다. django.setup()모델 클래스를 가져 오기 전에 전화 를 걸어야했는데 이것이 파일의 상단에 있었기 때문에 IoC 인젝터 구성으로 인해 장고가 아닌 라이브러리 코드로 드래그되었습니다.

나는 약간의 해킹으로 django.setup()인해 싱글 톤 생성자와 각 클래스 메소드의 맨 위에 관련 가져 오기를 넣었습니다 . 수입품이 최고가 아니었기 때문에 이것이 잘 작동했지만 불안해졌으며 수입품의 추가 시간 히트에 대해 걱정하기 시작했습니다. 그리고 나는 여기에 와서 모두가 이것에 대해 큰 관심을 가지고 읽었습니다.

나는 긴 C ++ 배경을 가지고 있으며 이제 Python / Cython을 사용합니다. 이것에 대한 내 취지는 프로파일 병목 현상을 일으키지 않는 한 수입품을 함수에 넣지 않는 이유입니다. 변수를 필요로하기 직전에 변수를위한 공간을 선언하는 것과 같습니다. 문제는 상단에 모든 수입품이있는 수천 줄의 코드가 있다는 것입니다! 그래서 나는 지금부터 그것을하고 내가 통과하고 시간을 가질 때 이상한 파일을 여기 저기 변경 할 것이라고 생각합니다.

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