내부 함수를 가져오는 것이 파이썬적입니까?
- 가져오기는 항상 파일의 맨 위, 모듈 주석 및 문서 문자열 바로 뒤, 모듈 전역 및 상수 앞에 배치됩니다.
가끔, 저는 PEP 8을 위반합니다.가끔 함수 안에 있는 것들을 가져오기도 합니다.일반적으로 단일 기능 내에서만 사용되는 가져오기가 있을 경우 이 작업을 수행합니다.
의견 있으십니까?
EDIT(기능에서 가져오는 것이 좋은 생각이라고 생각하는 이유):
주요 이유:그것은 코드를 더 명확하게 만들 수 있습니다.
- 함수의 코드를 볼 때 "function/class xxx가 무엇입니까?"(xxx는 함수 내부에서 사용됨)라고 자문할 수 있습니다.모듈 상단에 모든 가져오기가 있으면 xxx가 무엇인지 확인하러 가야 합니다.은 이은사때더됩문니다제가욱을 할 때 더 .from m import xxx.보고있습니다m.xxx아마도 더 많은 것을 말해줄 것입니다.에 따라mis: 잘 알려진 최상위 모듈/패키지(import m()입니까? 또는 서브모듈/패키지(from a.b.c import m)?
- 경우에 따라 xxx가 사용되는 위치 근처에 추가 정보("xxx란 무엇입니까?")가 있으면 기능을 더 쉽게 이해할 수 있습니다.
장기적으로 볼 때 대부분의 가져오기 작업을 파일 맨 위에 배치하면 모듈이 가져올 내용에 따라 얼마나 복잡한지 한눈에 알 수 있습니다.
기존 파일에 새 코드를 추가하는 경우에는 보통 필요한 위치에서 가져오기를 수행하고 코드가 유지되는 경우에는 가져오기 줄을 파일의 맨 위로 이동하여 영구적인 작업을 수행합니다.
한 가지 더 말씀드리자면, 저는 더 좋은 점이 있습니다.ImportError코드가 실행되기 전에 예외가 발생합니다. -- 건전성 검사로서, 이것이 맨 위에서 가져와야 하는 또 다른 이유입니다. 
사용합니다pyChecker사용되지 않는 모듈을 확인합니다.
이와 관련하여 제가 PEP 8을 위반하는 경우는 두 가지가 있습니다.
- 순환 가져오기: 모듈 A는 모듈 B를 가져오지만 모듈 B의 일부는 모듈 A가 필요합니다(단, 이는 순환 종속성을 제거하기 위해 모듈을 리팩터링해야 한다는 신호인 경우가 많음).
- : pdb 단점삽:import pdb; pdb.set_trace()이것은 쓰기 싫은 편리한 b/c입니다.import pdb디버깅하려는 모든 모듈의 맨 위에 있으며 중단점을 제거할 때 가져오기를 제거하는 것을 쉽게 기억할 수 있습니다.
이 두 가지 경우를 제외하고 모든 것을 맨 위에 두는 것이 좋습니다.그것은 의존성을 더 명확하게 만듭니다.
다음은 우리가 사용하는 네 가지 수입 사용 사례입니다.
- import)- from x import y그리고.- import x as y
- 가져오기를 선택합니다.맨 위에. - import settings if setting.something: import this as foo else: import that as foo
- 조건부 가져오기.JSON, XML 라이브러리 등과 함께 사용됩니다.맨 위에. - try: import this as foo except ImportError: import that as foo
- 동적 가져오기.지금까지, 우리는 이것에 대한 단 하나의 예를 가지고 있습니다. - import settings module_stuff = {} module= __import__( settings.some_module, module_stuff ) x = module_stuff['x']- 이 동적 가져오기는 코드를 가져오는 것이 아니라 Python으로 작성된 복잡한 데이터 구조를 가져옵니다.이것은 우리가 손으로 절인 것을 제외하고는 절인 데이터와 같습니다. - 이것은 또한 거의 모듈의 상단에 있습니다. 
코드를 보다 명확하게 하기 위해 수행하는 작업은 다음과 같습니다.
- 모듈을 짧게 유지합니다. 
- 모듈 상단에 모든 가져오기가 있으면 이름이 무엇인지 확인하기 위해 그곳을 찾아봐야 합니다.모듈이 짧으면 쉽게 할 수 있습니다. 
- 경우에 따라 이름이 사용되는 위치와 가까운 추가 정보를 사용하면 기능을 더 쉽게 이해할 수 있습니다.모듈이 짧으면 쉽게 할 수 있습니다. 
한 가지 명심해야 할 것은 불필요한 수입은 성능 문제를 야기할 수 있다는 것입니다.따라서 이 기능이 자주 호출될 기능이라면 가져오기를 맨 위에 놓는 것이 좋습니다.물론 이것은 최적화이므로, 파일의 맨 위에서 가져오는 것보다 함수 내부에서 가져오는 것이 더 명확하다는 타당한 사례가 있다면, 대부분의 경우 성능을 능가합니다.
IronPython을 하고 있다면, 내부 함수를 가져오는 것이 좋다고 들었습니다(IronPython의 코드 컴파일이 느릴 수 있기 때문입니다).따라서 내부 함수를 가져올 수도 있습니다.하지만 그것을 제외하면, 저는 관습과 싸우는 것은 가치가 없다고 주장할 것입니다.
일반적으로 단일 기능 내에서만 사용되는 가져오기가 있을 경우 이 작업을 수행합니다.
제가 말씀드리고 싶은 또 다른 요점은 이것이 잠재적인 유지 관리 문제일 수 있다는 것입니다.기존에 하나의 기능만 사용하던 모듈을 사용하는 기능을 추가하면 어떻게 됩니까?파일 맨 위에 가져오기를 추가하는 것을 기억하시겠습니까?아니면 수입을 위해 모든 기능을 스캔할 건가요?
FWIW, 함수 내부에서 가져오는 것이 타당한 경우가 있습니다.예를 들어 cx_Oracle에서 언어를 설정하려면 NLS를 설정해야 합니다._가져오기 전의 LANG 환경 변수입니다.따라서 다음과 같은 코드가 표시될 수 있습니다.
import os
oracle = None
def InitializeOracle(lang):
    global oracle
    os.environ['NLS_LANG'] = lang
    import cx_Oracle
    oracle = cx_Oracle
저는 자가 테스트를 하는 모듈에 대해 이 규칙을 어긴 적이 있습니다.즉, 일반적으로 지원 용도로만 사용되지만, 직접 실행하면 기능을 테스트할 수 있도록 메인을 정의합니다.그런 경우에는 가끔 수입을 합니다.getopt그리고.cmd코드를 읽는 누군가에게 이 모듈들이 모듈의 정상적인 작동과는 아무런 관련이 없으며 테스트용으로만 포함되어 있다는 것을 분명히 하고 싶기 때문입니다.
모듈을 두 번 로드하는 것과 관련된 질문에서 나온 것입니다. 두 가지 모두 로드하는 것이 어떻습니까?
스크립트의 맨 위에 있는 가져오기는 종속성을 나타내고 함수의 다른 가져오기는 이 함수를 더 원자적으로 만들지만, 연속 가져오기는 저렴하기 때문에 성능 저하를 초래하지는 않습니다.
sqlalchemy에서 사용되는 대체 접근 방식인 종속성 주입을 살펴봅니다.
@util.dependencies("sqlalchemy.orm.query")
def merge_result(query, *args):
    #...
    query.Query(...)
가져온 라이브러리가 데코레이터에서 선언되고 함수의 인수로 전달되는 방식에 주목하십시오!
이 접근 방식은 코드를 더 깨끗하게 만들며, 또한 4.5배 더 빠르게 작동합니다.import진술!
벤치마크: https://gist.github.com/kolypto/589e84fbcfb6312532658df2fabdb796
다른 (아마도 "모서리") 사례가 있습니다.import거의 사용하지 않는 함수 내부: 시작 시간 단축.
저는 작은 IoT 서버에서 실행되는 다소 복잡한 프로그램으로 그 벽에 부딪힌 적이 있습니다. 직렬 라인에서 명령을 받고 작업을 수행합니다. 아마도 매우 복잡한 작업일 것입니다.
배치import서버가 시작되기 전에 모든 가져오기를 처리하도록 의미하는 파일의 맨 위에 있는 문.import포함된 리스트jinja2,lxml,signxml그리고 다른 "무거운 중량" (그리고 SoC는 그다지 강력하지 않았습니다) 이것은 첫 번째 명령이 실제로 실행되기 몇 분 전을 의미했습니다.
OTOH는 대부분의 가져오기를 기능에 배치했습니다. 서버를 몇 초 만에 직렬 라인에서 "활성화"할 수 있었습니다.물론 모듈이 실제로 필요할 때는 비용을 지불해야 했습니다. (참고: 이는 백그라운드 작업을 생성함으로써 완화될 수 있습니다.)imports 유휴 시간).
그것이 있는 한import그리고 아닌from x import *당신은 그것들을 맨 위에 놓아야 합니다.글로벌 네임스페이스에 이름을 하나만 추가하면 PEP 8을 그대로 유지할 수 있습니다.또한 나중에 다른 곳에서 필요할 경우에는 다른 곳으로 이동할 필요가 없습니다.
큰 문제는 아니지만, 거의 차이가 없기 때문에 저는 PEP 8이 말하는 것을 하는 것을 제안하고 싶습니다.
 '' 모듈, '고장' 모듈)입니다.if __name__ == '__main__': 저는 section .-section), 저는주로메인섹모듈실을행때할만사다모용는가니듈져옵.
예:
def really_useful_function(data):
    ...
def main():
    from pathlib import Path
    from argparse import ArgumentParser
    from dataloader import load_data_from_directory
    parser = ArgumentParser()
    parser.add_argument('directory')
    args = parser.parse_args()
    data = load_data_from_directory(Path(args.directory))
    print(really_useful_function(data)
if __name__ == '__main__':
    main()
언급URL : https://stackoverflow.com/questions/1024049/is-it-pythonic-to-import-inside-functions
'programing' 카테고리의 다른 글
| 옵션 매개 변수를 함수에 전달하는 방법이 있습니까? (0) | 2023.07.23 | 
|---|---|
| mysql 테이블에서 datetime x min ago와 datetime x min ago 사이에서 선택 (0) | 2023.07.23 | 
| gem_point에 점 레이블 지정 (0) | 2023.07.18 | 
| 누가 StandardScaler에 대해 설명해 줄 수 있습니까? (0) | 2023.07.18 | 
| 프로그래밍 방식으로 spring-boot-metric에서 메트릭을 가져오는 방법은 무엇입니까? (0) | 2023.07.18 |