python - 这个 lambda 函数是否有理由保留“self”的“旧实例”?
问题描述
这个错误有一个故事可以提供进一步的上下文:我编写了这段代码,因为如果我在内部创建一个带有 lambda 函数的 SQLAlchemy 关系,它只会在创建所有模型后初始化关系。它所做的基本上是将所有模型填充到字典 ( self._all_models
) 中,然后 lambda 函数稍后将通过访问 ( self._all_models[table_name]['model']
) 获取模型。因此,当我执行 a 时session.add(Model)
,将调用此 lambda 函数并尝试从字典中获取模型。
我执行得很好,但我的同事有一个奇怪的问题:self
实例是“旧的”,我的意思是字典self._all_models
只有迄今为止创建的模型,而不是所有模型。例如,如果它必须创建 3 个模型 ( a
, b
, ),当要调用关系中c
的 lambda 时,将只有而不是全部 3 ( )。b
self._all_models
{'a': ...}
{'a': ..., 'b': ..., 'c': ...}
我和我的同事之间唯一的区别是我运行 Python 3.9,而他们运行 Python 3.8。当我的一位同事——“Jack”——将他的 Python 升级到 3.9 时,它运行顺利(即使在改回他的 3.8 venv 之后);但我的另一位同事——“马克”——就没有那么幸运了:即使在升级之后,它仍然对他不起作用。
比较他们的库pip freeze
并没有发现任何不同,问题不太可能出在 SQLAlchemy 上。
代码:
class ORM:
def __init__(self, source_name: str, ..., address_http_protocol: str):
self._all_models = defaultdict(lambda: {})
...
self._create_all_models()
...
def _create_all_models(self) -> None:
base = declarative_base()
base.metadata.reflect(self._get_engine())
all_tables = base.metadata.tables
for table in all_tables.values():
current_table_name = table.name
relationships = self._get_parents(table)
obj = type(current_table_name, (object,), dict())
mapper(obj, table,
properties={table_name: relationship(lambda table_name=table_name:
self._get_model_by_table_name(table_name), lazy='select')
for table_name in relationships})
self._all_models[current_table_name]['model'] = obj
self._all_models[current_table_name]['table'] = table
@staticmethod
def _get_parents(table: Table) -> set:
parents = set()
if table.foreign_keys:
for fk in table.foreign_keys:
parent_name = fk.column.table.name
parents.add(parent_name) if parent_name != table.name else None
return parents
def _get_model_by_table_name(self, table_name: str) -> type:
if isinstance(table_name, str):
return self._all_models[table_name]['model']
我说的是里面的 lambda 函数_create_all_models
:lambda table_name=table_name: self._get_model_by_table_name(table_name)
。
解决方案
所以显然问题在于self._all_models
字典绑定到__init__
函数,这使它成为“本地”并且没有“访问”权self
。
更多内容:函数、未绑定方法和绑定方法有什么区别?
推荐阅读
- c# - MonoBehavior 中的声明调用构造函数并崩溃
- javascript - 我想点击图片的一部分来获取标题
- powerbi - DAX 测量以计算具有特定背景单元格颜色的行
- javascript - 尝试在反应示例应用程序中列出信封时出现 404 错误
- javascript - 如何使用 fetch() javascript 方法将数据发布到 .NET Core Web API
- ios - 使用 Swift 包管理器时单元测试中的“缺少所需的模块‘XYZ’”
- c# - POST 操作返回“未找到”错误
- php - 如何使用 Mysql If 函数来评估日期时间列?
- powershell - 尝试 Catch 不适用于 Get-CsUser 命令
- mysql - 如何在 SELECT 中将语句从一个表替换到另一个表?