programing

내부 함수를 가져오는 것이 파이썬적입니까?

oldcodes 2023. 7. 18. 21:57
반응형

내부 함수를 가져오는 것이 파이썬적입니까?

PEP 8은 다음과 같이 말합니다.

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

가끔, 저는 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디버깅하려는 모든 모듈의 맨 위에 있으며 중단점을 제거할 때 가져오기를 제거하는 것을 쉽게 기억할 수 있습니다.

이 두 가지 경우를 제외하고 모든 것을 맨 위에 두는 것이 좋습니다.그것은 의존성을 더 명확하게 만듭니다.

다음은 우리가 사용하는 네 가지 수입 사용 사례입니다.

  1. import)from x import y그리고.import x as y

  2. 가져오기를 선택합니다.맨 위에.

    import settings
    if setting.something:
        import this as foo
    else:
        import that as foo
    
  3. 조건부 가져오기.JSON, XML 라이브러리 등과 함께 사용됩니다.맨 위에.

    try:
        import this as foo
    except ImportError:
        import that as foo
    
  4. 동적 가져오기.지금까지, 우리는 이것에 대한 단 하나의 예를 가지고 있습니다.

    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

반응형