在 Python 中键入提示受保护/私有类的正确方法?

Correct way to type hint protected / private classes in Python?

提问人:opnightfall1771 提问时间:12/11/2021 最后编辑:Emiliano Viottiopnightfall1771 更新时间:4/30/2023 访问量:1248

问:

我这里有一个示例类,我想使用 lxml 来解析 xml 文件。

class XMLParser:

    def __init__(self, path: str):
        self.root: etree._Element | None = None

但是,当我使用此类型提示时,PyCharm 会抱怨对受保护成员的访问_Element。有没有更正确的方法来注释这样的变量?当我键入 check this 时,_Element类是正确的。

感谢您的帮助!

Python 注解 lxml 类型提示

评论

2赞 AbbeGijly 12/11/2021
Python 没有正式声明 private / protected 的方法,但有一个通用的约定,即使用单个前导下划线(如 )来指示模块本地或类本地符号。PyCharm 给你一个警告,但你的代码是完全合法的 python;在某些圈子里,它只是被认为是“不礼貌的”_Element
0赞 opnightfall1771 12/11/2021
这是有道理的。我想作为后续,有没有一种“礼貌”的方式来键入提示受保护的类?或者在这种情况下最好不使用类型提示?
0赞 Samwise 12/11/2021
如果你在另一个类中使用它,就像你在这里一样,它不是“受保护的”,你应该把它重命名为正式的接口的一部分。Python 没有任何“友元类”的概念,即使按照惯例——如果你认为将这个类视为“受保护的”是合适的,但需要做一个特定的例外,请使用 Pycharm 的 linter 覆盖或任何适当的 linter 覆盖。Element# pylint: ignore
1赞 juanpa.arrivillaga 12/11/2021
@Samwise我相信这是来自图书馆lxml
1赞 Samwise 12/11/2021
啊,一个包装实际类的工厂也是如此,他们从未打算让你直接使用它,因为他们没有考虑类型注释。是的!看起来您可能需要 pypi.org/project/lxml-stubs 才能正确注释这些内容?我认为有可能使它以一种很好的方式工作。etree.Elementetree._ElementProtocol

答:

1赞 Abel Cheung 4/30/2023 #1

OP 的最佳方法是忽略警告。根据我几年的 lxml 类型注解经验,“public”/“private”-ness 和类名没有明确的关系——一些用户无法构造的私有结构具有类似 public-class 的名称(公开导出,不带下划线,如)。PyCharmDocInfo

尽管作者似乎将其声明为“私有”,但 lxml 用户根本无法在函数签名中避免它。其他“私有”类也是如此,如 等。etree._Element_ElementTree_Comment