Làm cách nào để kiểm tra xem một mô-đun python đã được nhập chưa?


91

Làm cách nào để kiểm tra xem tôi đã nhập một mô-đun ở đâu đó trong mã?

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

Lý do mà tôi muốn kiểm tra xem tôi đã nhập một mô-đun chưa là vì tôi có một mô-đun mà tôi không muốn nhập vì đôi khi nó làm rối chương trình của tôi.


Chỉ cần đặt raise SystemError()(hoặc ngoại lệ khác mà bạn chọn) ở đầu mô-đun mà bạn không muốn nhập. Nếu bạn làm thực sự nhập nó ở đâu đó, chương trình của bạn sẽ ném một traceback và thoát.
larsks

Làm thế nào mà việc chỉ nhập một mô-đun lại làm rối tung chương trình của bạn? Không có vẻ như vậy.
Bill Woodger


@MartijnPieters Yoiks. Và nhập khẩu âm thanh rất trung lập.
Bill Woodger

Câu trả lời:


122

Kiểm tra tên mô-đun trong sys.modulestừ điển :

import sys

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

Từ tài liệu:

Đây là một từ điển ánh xạ tên mô-đun đến các mô-đun đã được tải.

Lưu ý rằng một importcâu lệnh thực hiện hai điều:

  1. nếu mô-đun chưa bao giờ được nhập trước đây (== không có trong sys.modules), thì nó sẽ được tải và thêm vào sys.modules.
  2. Liên kết 1 hoặc nhiều tên trong không gian tên hiện tại tham chiếu đến đối tượng mô-đun hoặc đến các đối tượng là thành viên của không gian tên mô-đun.

Kiểm modulename not in sys.modulestra biểu thức nếu bước 1 đã diễn ra. Kiểm tra kết quả của bước 2 yêu cầu biết importcâu lệnh chính xác nào đã được sử dụng khi chúng đặt các tên khác nhau để tham chiếu các đối tượng khác nhau:

  • import modulename bộ modulename = sys.modules['modulename']
  • import packagename.nestedmodulebộ packagename = sys.modules['packagename'](bất kể bạn thêm bao nhiêu cấp độ bổ sung)
  • import modulename as altname bộ altname = sys.module['modulename']
  • import packagename.nestedmodule as altname bộ altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname bộ objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulenamebộ nestedmodulename = sys.modules['packagename.nestedmodulename'](chỉ khi không có đối tượng nào được đặt tên nestedmodulenametrong packagenamekhông gian tên trước lần nhập này, tên bổ sung cho mô-đun lồng nhau được thêm vào không gian tên gói mẹ tại thời điểm này)
  • from somemodule import objectname as altname bộ altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altnamebộ altname = sys.modules['packagename.nestedmodulename'](chỉ khi không có đối tượng nào được đặt tên nestedmodulenametrong packagenamekhông gian tên trước lần nhập này, tên bổ sung cho mô-đun lồng nhau được thêm vào không gian tên gói mẹ tại thời điểm này)

Bạn có thể kiểm tra xem tên mà đối tượng được nhập bị ràng buộc có tồn tại trong một không gian tên nhất định hay không:

# 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'])

Điều này chỉ cho bạn biết tên tồn tại (đã bị ràng buộc), không phải nếu nó đề cập đến một mô-đun hoặc đối tượng cụ thể từ mô-đun đó. Bạn có thể tìm hiểu sâu hơn về đối tượng đó hoặc kiểm tra xem nó có giống đối tượng với những thứ có sẵn trong đó không sys.modules, nếu bạn cần loại trừ rằng tên đã được đặt hoàn toàn khác kể từ đó.


1
Đây có phải là cách tốt nhất để kiểm tra gói bắt buộc bên trong một hàm không? Đó là, giả sử một số hàm yêu cầu numpygói - việc sử dụng import sysbên trong hàm là cách tốt nhất để kiểm tra xem nó đã được nhập chưa? Ý tôi là "tốt nhất" về tác động hiệu suất khi đó import syssẽ được gọi mỗi khi hàm được gọi. Cảm ơn bạn
Bối rối

@Con Founder bạn có thể chỉ cần nhập hệ thống bên ngoài chức năng nếu điều đó làm bạn lo lắng. Điều đó không phải import syslà đắt tiền; sysluôn tồn tại, theo mặc định nó đã được tải. Nhưng đối với gói tùy chọn: chỉ cần nhập gói . Nắm bắt ImportErrorngoại lệ nếu gói chưa được cài đặt và đặt cờ cho biết gói đã được cài đặt khi nhập thành công. Sau đó, bạn có thể sử dụng cờ để thông báo việc sử dụng phụ thuộc tùy chọn của bạn.
Martijn Pieters

@Con Found name in sys.modulesThử nghiệm chỉ hữu ích nếu bạn không muốn nhập .
Martijn Pieters

24

Đối với các câu trả lời sys.modules được chấp nhận, tôi sẽ thêm một lưu ý là hãy cẩn thận về việc đổi tên các mô-đun khi nhập:

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

18

sử dụng sys.modules để kiểm tra xem một mô-đun đã được nhập chưa (tôi đang sử dụng dữ liệu unicoded làm ví dụ):

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

5

sys.modules chứa tất cả các mô-đun được sử dụng ở bất kỳ đâu trong phiên bản hiện tại của trình thông dịch và do đó sẽ hiển thị nếu được nhập vào bất kỳ mô-đun Python nào khác.

dir() kiểm tra xem tên đã được xác định trong không gian tên hiện tại hay chưa.

Sự kết hợp của cả hai an toàn hơn so với từng loại riêng biệt và hoạt động miễn là bạn không xác định copychính mình.

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

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

Điều đó chỉ kiểm tra xem mô-đun đã được nhập vào không gian tên hiện tại hay chưa. Ngoài ra syscó thể là bất cứ thứ gì, không chỉ là một mô-đun.
vaultah
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.