파이썬 모듈을 가져 왔는지 확인하는 방법은 무엇입니까?


91

코드의 어딘가에 모듈을 가져 왔는지 어떻게 확인합니까?

 if not has_imported("somemodule"):
     print('you have not imported somemodule')

내가 이미 모듈을 가져 왔는지 확인하고 싶은 이유는 가끔 내 프로그램을 엉망으로 만들기 때문에 가져오고 싶지 않은 모듈이 있기 때문입니다.


raise SystemError()가져오고 싶지 않은 모듈의 맨 위에 놓기 만하면됩니다 (또는 선택한 다른 예외). 당신이 경우 않습니다 실제로 어딘가에을 가져, 프로그램은 추적 종료가 발생합니다.
Larsks

어쨌든 모듈을 가져 오는 것이 프로그램을 어떻게 엉망으로 만들까요? 그렇게 들리지 않습니다.
Bill Woodger 2015 년

1
@BillWoodger : 아마도 해당 모듈은 변경하고 싶지 않은 전역 상태를 변경 합니다.
Martijn Pieters

트윗 담아 가기 그리고 매우 중립적 인 사운드를 가져옵니다.
Bill Woodger 2015 년

답변:


122

sys.modules사전 에서 모듈 이름을 테스트하십시오 .

import sys

modulename = 'datetime'
if modulename not in sys.modules:
    print 'You have not imported the {} module'.format(modulename)

문서에서 :

이미로드 된 모듈에 모듈 이름을 매핑하는 사전입니다.

참고 import문이 두 가지를 수행합니다 :

  1. 모듈을 이전에 가져온 적이없는 경우 (==에 존재하지 않음 sys.modules),로드되고에 추가됩니다 sys.modules.
  2. 모듈 개체를 참조하는 현재 네임 스페이스 또는 모듈 네임 스페이스의 멤버 인 개체에 하나 이상의 이름을 바인딩합니다.

표현식 modulename not in sys.modules은 1 단계가 수행되었는지 테스트합니다. 2 단계의 결과를 테스트하려면 import서로 다른 개체를 참조하기 위해 서로 다른 이름을 설정하므로 사용 된 정확한 문을 알아야 합니다.

  • import modulename 세트 modulename = sys.modules['modulename']
  • import packagename.nestedmodule세트 packagename = sys.modules['packagename'](추가 수준에 관계없이)
  • import modulename as altname 세트 altname = sys.module['modulename']
  • import packagename.nestedmodule as altname 세트 altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname 세트 objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename집합 nestedmodulename = sys.modules['packagename.nestedmodulename']( 이 가져 오기 전에 네임 스페이스에 명명 nestedmodulename된 개체가없는 경우에만 packagename중첩 된 모듈의 추가 이름이이 시점에서 상위 패키지 네임 스페이스에 추가됨)
  • from somemodule import objectname as altname 세트 altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altname집합 altname = sys.modules['packagename.nestedmodulename']( 이 가져 오기 전에 네임 스페이스에 명명 nestedmodulename된 개체가없는 경우에만 packagename중첩 된 모듈의 추가 이름이이 시점에서 상위 패키지 네임 스페이스에 추가됨)

가져온 객체가 바인딩 된 이름이 주어진 네임 스페이스에 있는지 테스트 할 수 있습니다.

# is this name visible in the current scope:
'importedname' in dir()

# or, is this a name in the globals of the current module:
'importedname' in globals()

# or, does the name exist in the namespace of another module:
'importedname' in globals(sys.modules['somemodule'])

이것은 해당 모듈의 특정 모듈이나 개체를 참조하는 경우가 아니라 이름이 존재 함 (바인딩 됨) 만 알려줍니다. sys.modules그 이후로 이름이 완전히 다른 것으로 설정되었음을 배제해야하는 경우 해당 객체를 추가로 검사하거나에서 사용 가능한 객체와 동일한 객체인지 테스트 할 수 있습니다 .


1
함수 내에서 필요한 패키지를 확인하는 가장 좋은 방법입니까? 즉, 일부 기능에 numpy패키지가 필요하다고 가정합니다. 함수 import sys내부를 사용하여 가져 왔는지 확인하는 것이 가장 좋습니까? "최상"이란 import sys함수가 호출 될 때마다 호출 되는 성능 영향 측면에서 의미 합니다. 주셔서 감사합니다
망할 것

@Confounded 당신이 걱정한다면 단순히 함수 외부에서 sys를 가져올 수 있습니다. 그것은 import sys결코 비싸지 않습니다. sys항상 존재하며 기본적으로 이미로드되어 있습니다. 그러나 선택적 패키지의 경우 : 패키지를 가져 오십시오 . ImportError패키지가 설치되지 않은 경우 예외를 포착하고 가져 오기가 성공하면 설치되었음을 나타내는 플래그를 설정하십시오. 그런 다음 플래그를 사용하여 선택적 종속성을 사용할 수 있습니다.
Martijn Pieters

@Confounded이 name in sys.modules테스트는 가져 오기를 원하지 않는 경우에만 유용합니다 .
Martijn Pieters

24

허용되는 sys.modules 답변에 가져올 때 모듈 이름을 바꿀 때주의해야 할 한 가지주의 사항을 추가합니다.

>>> import sys
>>> import datetime as dt
>>> 'dt' in sys.modules
False
>>> 'datetime' in sys.modules
True

18

sys.modules를 사용하여 모듈을 가져 왔는지 테스트합니다 (예로 unicodedata를 사용하고 있습니다).

>>> import sys
>>> 'unicodedata' in sys.modules
False
>>> import unicodedata
>>> 'unicodedata' in sys.modules
True

5

sys.modules 인터프리터의 현재 인스턴스에서 사용되는 모든 모듈을 포함하므로 다른 Python 모듈에서 가져온 경우 표시됩니다.

dir() 이름이 현재 네임 스페이스에 정의되었는지 확인합니다.

2의 조합은 각각의 조합보다 안전하며 copy자신을 정의하지 않는 한 작동합니다 .

if ('copy' in sys.modules) and ('copy' in dir()):

0
if "sys" not in dir():
  print("sys not imported!")

현재 네임 스페이스에서 모듈을 가져 왔는지 여부 만 확인합니다. 또한 sys모듈뿐만 아니라 무엇이든 될 수 있습니다.
vaultah
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.