Databricks跨Notebook调用类出现“gpg_encryption未定义”错误求助
问题原因分析
你遇到的核心问题是**dbutils.notebook.run的执行机制导致的上下文隔离**:
dbutils.notebook.run会启动一个完全独立的执行会话,notebook1和notebook2的内存空间、变量上下文完全不共享,notebook2中定义的类无法直接被notebook1访问。dbutils.notebook.exit()仅支持返回字符串类型,你传入gpg_encryption类时,实际返回的是类的字符串描述(如<class '__main__.gpg_encryption'>),而非可实例化的类对象,因此notebook1中会提示“名称未定义”。
解决方案
方案一:用%run结合组件传参(推荐,同会话共享上下文)
%run本身支持通过dbutils.widgets传递参数,且两个notebook会在同一会话执行,类定义直接生效:
步骤1:在notebook2中配置参数接收
# 定义接收参数的组件 dbutils.widgets.text("CATALOG", "") dbutils.widgets.text("STORAGEACCOUNT_NAME", "") # 获取参数 CATALOG = dbutils.widgets.get("CATALOG") STORAGEACCOUNT_NAME = dbutils.widgets.get("STORAGEACCOUNT_NAME") # 定义gpg_encryption类 import gnupg class gpg_encryption(gnupg.GPG): def __init__(self): super().__init__() # 用传入的参数初始化类属性 self.catalog = CATALOG self.storage_account = STORAGEACCOUNT_NAME # 其他自定义逻辑
步骤2:在notebook1中调用并传参
# 设置组件参数值 dbutils.widgets.text("CATALOG", f"{CATALOG}") dbutils.widgets.text("STORAGEACCOUNT_NAME", f"{STORAGEACCOUNT_NAME}") # 运行notebook2,类定义会加载到当前会话 %run ./path/to/notebook2 # 直接实例化类 gpg_handler = gpg_encryption()
方案二:将类定义放到共享Python模块(最佳实践)
把gpg_encryption类的代码抽离为独立模块,在notebook1中直接导入并传参:
步骤1:创建共享模块文件
在DBFS或工作区库中创建gpg_utils.py:
import gnupg class gpg_encryption(gnupg.GPG): def __init__(self, catalog, storage_account): super().__init__() self.catalog = catalog self.storage_account = storage_account # 其他自定义逻辑
步骤2:在notebook1中导入并使用
# 添加模块路径(如果放在DBFS) import sys sys.path.append("/dbfs/FileStore/modules/") # 导入类并实例化 from gpg_utils import gpg_encryption gpg_handler = gpg_encryption(CATALOG, STORAGEACCOUNT_NAME)
方案三:动态执行返回的类代码(不推荐,仅作应急)
如果必须使用dbutils.notebook.run,可将类定义转为字符串返回,在notebook1中动态执行:
步骤1:notebook2中返回类代码字符串
dbutils.widgets.text("CATALOG", "") dbutils.widgets.text("STORAGEACCOUNT_NAME", "") CATALOG = dbutils.widgets.get("CATALOG") STORAGEACCOUNT_NAME = dbutils.widgets.get("STORAGEACCOUNT_NAME") # 将类定义转为带参数的字符串 class_code = f""" import gnupg class gpg_encryption(gnupg.GPG): def __init__(self): super().__init__() self.catalog = "{CATALOG}" self.storage_account = "{STORAGEACCOUNT_NAME}" """ dbutils.notebook.exit(class_code)
步骤2:notebook1中动态执行代码
# 获取类代码字符串 class_code = dbutils.notebook.run(path, 60, {"CATALOG": f"{CATALOG}", "STORAGEACCOUNT_NAME": f"{STORAGEACCOUNT_NAME}"}) # 动态执行代码,生成类 exec(class_code) # 实例化类 gpg_handler = gpg_encryption()
内容的提问来源于stack exchange,提问作者play_something_good
相关产品推荐
相关产品推荐

