当 SQLAlchemy backrefs 变得复杂时,它们往往会导致循环导入,所以我想出了一种方法来“重新打开”Python 类,就像在 Ruby 中一样:
def reopen(cls):
"""
Moves the contents of the decorated class into an existing class and returns that.
Usage::
from .other_module import ExistingClass
@reopen(ExistingClass)
class ExistingClass:
@property
def new_property(self):
pass
This is equivalent to::
def new_property(self):
pass
ExistingClass.new_property = property(new_property)
"""
def decorator(temp_cls):
for attr, value in temp_cls.__dict__.items():
# Skip the standard Python attributes, process the rest
if attr not in ('__dict__', '__doc__', '__module__', '__weakref__'):
setattr(cls, attr, value)
return cls
return decorator
这是一个简化版本; the full implementation has more safety checks和测试。
当 SQLAlchemy 的现有关系+backref 机制不够用时,这段代码可以很好地插入双向 SQLAlchemy 关系和辅助方法。
但是:
我可以通过在线注释(# type: ignore
和 #skipcq
)来忽略这两个错误,但是过度使用这些注释可能会让错误漏掉。告诉 mypy 和 pylint 这种用法没问题就好了。
我该怎么做?
最佳答案
作为解决方法,我已切换到此模式:
@reopen(ExistingClass)
class __ExistingClass:
@property
def new_property(self):
pass
>>> assert __ExistingClass is ExistingClass
True
Pylint 和 Mypy 不再提示重定义。但是,Mypy 不会将 ExistingClass.new_property
识别为类的附加项,因此它会将问题踢到使用它的代码下游。
我的印象是,虽然多次讨论了此类类扩展 hack,但作为一种编码模式并没有获得足够的吸引力,在 Mypy 的情况下,这将需要一个自定义插件。
https://stackoverflow.com/questions/64444293/
相关文章:
javascript - 从 MapBox GL JS 中的聚类中排除某些功能
json - 如何在 Django 中使用多对多关系加载 fixtures.json
python - 为什么 patch.contains_point() 在检查点是否在多边形内时与
ios - 带有 iOS 14 设备的 Xcode 10 - 尝试与此设备通信时遇到错误。 (该服务
python-3.x - python 中的 sys.exit 给出一个 SystemExit 错误
apache-spark - 无法使用 Apache Hudi 编写非分区表
python - 来自代码编辑器的 common.py 文件的断言错误