python - 在 pylint 和 mypy 中处理 Python 类重新定义警告

当 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 关系和辅助方法。

但是:

  1. mypy 引发错误“名称‘ExistingClass’已定义(可能通过导入)”
  2. pylint 引发 E0102“类已定义”

我可以通过在线注释(# 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 文件的断言错误

react-native - 在 React Native 中的数组或对象内部时,i18n 无法正确

python - 无法找到具有前瞻/后视功能的正则表达式

reactjs - 无法查询类型 "x"上的字段 "y"