gpt4 book ai didi

从装饰器导入 Python 模块

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:16 27 4
gpt4 key购买 nike

我正在使用 Python 3 开发一个应用程序,我所做的是非常规的。

cx_Oracle 是一个很难设置的模块,对于我的应用程序来说是一个可选的依赖项。我想做的是将模块的导入包装在装饰器中,仅放置在使用它的函数之上。这将避免在我的模块顶部导入并允许它不被设置。

class Loader():
def load_cx_oracle(func):
def inner(*args, **kwargs):

# Additional code before import.

import cx_Oracle

return func(*args, **kwargs)
return inner

@load_cx_oracle
def function_using_cx_oracle(self):
conn = cx_Oracle.connect()

但是,当我尝试上述操作时,我得到了 NameError: name 'cx_Oracle' is not defined

最佳答案

接受的答案有几个问题。其中最重要的是每次调用该函数时它都会运行导入逻辑。第二个是装饰器必须在它使用的同一个模块中定义,否则装饰器和被装饰器将具有不同的全局变量。您可以通过函数的 __globals__ 属性直接访问函数的全局变量。在执行导入逻辑之前,代码示例首先检查模块是否存在于函数的全局变量中。该示例还使用 functools.wraps 装饰器在使用 help(func) 时保留文档字符串、函数名称和参数名称。

from functools import wraps

def load_operator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if "operator" not in func.__globals__:
# setup logic -- only executed once
import operator
func.__globals__["operator"] = operator
return func(*args, **kwargs)
return wrapper

class A:
@load_operator
def add(self, x, y):
return operator.add(x, y)

def subtract(self, x, y):
return operator.subtract(x, y)

a = A()
try:
a.subtract(1, 2)
except NameError:
print("operator not yet loaded")
print(a.add(1, 2))
print(A.add)

关于从装饰器导入 Python 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29018731/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com