【发布时间】:2020-05-01 05:37:50
【问题描述】:
我正在尝试编写一个装饰器,在使用函数之前检查特定包是否可用。
在下面的示例中,numpy 不应引发错误,但 non_existent_test_package 应告知用户他们需要安装软件包才能使用此功能。这样做的目的是减少依赖。
根据@henry-harutyunyan 的建议更新
import numpy as np
import importlib
def check_available_packages(packages):
if isinstance(packages,str):
packages = [packages]
packages = np.asarray(sorted(set(packages)))
def wrapper(func):
installed = list()
for package in packages:
try:
globals()[package] = importlib.import_module(package)
installed.append(True)
except ImportError:
installed.append(False)
installed = np.asarray(installed)
assert np.all(installed), "Please install the following packages to use this functionality:\n{}".format(", ".join(map(lambda x: "'{}'".format(x), packages[~installed])))
return func
return wrapper
@check_available_packages(["numpy"])
def f():
print("This worked")
@check_available_packages(["numpy", "non_existent_test_package"])
def f():
print("This shouldn't work")
# ---------------------------------------------------------------------------
# AssertionError Traceback (most recent call last)
# <ipython-input-222-5e8224fb30bd> in <module>
# 23 print("This worked")
# 24
# ---> 25 @check_available_packages(["numpy", "non_existent_test_package"])
# 26 def f():
# 27 print("This shouldn't work")
# <ipython-input-222-5e8224fb30bd> in wrapper(func)
# 15 installed.append(False)
# 16 installed = np.asarray(installed)
# ---> 17 assert np.all(installed), "Please install the following packages to use this functionality:\n{}".format(", ".join(map(lambda x: "'{}'".format(x), packages[~installed])))
# 18 return func
# 19 return wrapper
# AssertionError: Please install the following packages to use this functionality:
# 'non_existent_test_package'
现在装饰器似乎在运行时检查包是否存在,而不是在实际调用函数时。如何调整此代码?
【问题讨论】:
-
check_available_packages是一个装饰器 factory,它返回一个装饰器,该装饰器必须接受一个参数——要装饰的函数。参见例如stackoverflow.com/q/5929107/3001761
标签: python module package decorator python-decorators