How to catch an ImportError non-recursively? (dyna

2019-09-18 09:56发布

Say we want to import a script dynamically, i.e. the name is constructed at runtime. I use this to detect plugin scripts for some program, so the script may not be there and the import may fail.

from importlib import import_module
# ...
subpackage_name = 'some' + dynamic() + 'string'
try:
    subpackage = import_module(subpackage_name)
except ImportError:
    print('No script found')

How can we make sure to only catch the possible import failure of the plugin script itself, and not of the imports that may be contained inside the plugin script?

Side note: this question is related, but is about static imports (using the import keyword), and the provided solutions don't work here.

2条回答
老娘就宠你
2楼-- · 2019-09-18 10:00

ImportErrors in Python have messages you can read name attributes you can use if you have the exception object:

# try to import the module
try:
    subpackage = import_module(subpackage_name)

# get the ImportError object
except ImportError as e:

    ## get the message
    ##message=e.message

    ## ImportError messages start with "No module named ", which is sixteen chars long.
    ##modulename=message[16:]

    # As Ben Darnell pointed out, that isn't the best way to do it in Python 3
    # get the name attribute:
    modulename=e.name

    # now check if that's the module you just tried to import
    if modulename==subpackage_name:
        pass

        # handle the plugin not existing here

    else:
        # handle the plugin existing but raising an ImportError itself here

# check for other exceptions
except Exception as e:
    pass
    # handle the plugin raising other exceptions here
查看更多
We Are One
3楼-- · 2019-09-18 10:24

Since Python 3.3, ImportError objects have had name and path attributes, so you can catch the error and inspect the name it failed to import.

try:
    import_module(subpackage_name)
except ImportError as e:
    if e.name == subpackage_name:
        print('subpackage not found')
    else:
        print('subpackage contains import errors')
查看更多
登录 后发表回答