【问题标题】:Is it a convention to prefix private classes with underscores?用下划线为私有类添加前缀是惯例吗?
【发布时间】:2011-09-30 11:11:48
【问题描述】:

我已经看到函数/常量带有下划线前缀的代码。 我的理解是,这表明它们不能直接使用。 我可以在课堂上做到这一点吗?

class _Foo(object):
    pass

class __Bar(object):
    pass

【问题讨论】:

  • __ 由 Python 保留。永远不要使用这个。在大多数情况下,它会导致名称修改问题。尽量避免认为这是有用的。尝试将其视为“保留”、“不用于一般用途”和“等待发生的问题”。然后,请把它从你的问题中解脱出来。
  • 请解释一下什么是“私人”课程。你能提供一个用例或你会使用它的情况吗?
  • 会有导出的函数供用户使用。在这些函数中,它将实例化这些“私有”类。
  • @guettli “模块迟早需要访问这个变量。” Python 的好处在于模块 仍然可以 访问该变量,即使您在变量前面加上下划线——您只是提供了一个提示,而不是强制执行任何操作。
  • “会有导出函数”? “导出功能”是什么意思?您似乎使用了很多来自其他编程语言的术语。

标签: python


【解决方案1】:

最好只使用一个_。这表明名称在模块中是私有的。

它不是用包罗万象的from <module> import * 导入的,它还有一些其他功能,例如“首选销毁”。

来自here

如果未定义__all__,则公共名称集包括所有名称 在不以下划线开头的模块命名空间中找到 字符('_')。

来自here

从 1.5 版开始,Python 保证名称以 在删除其他全局变量之前,会从其模块中删除单个下划线。

双下划线起始类成员是name-mangled

【讨论】:

  • 有人可以评论一下“首选销毁”的目的是什么吗?
【解决方案2】:

是的; PEP8 支持内部使用类的单下划线用法。

我不相信双下划线的使用在大多数情况下会产生任何实际影响,因为它用于对类属性进行主动名称修饰,并且通常一个类不是另一个类的属性(当然,它 可以,在这种情况下,Python 会很乐意为您修改名称。)

【讨论】:

    【解决方案3】:

    是的,这不仅仅是一个约定。当你从这个模块import * 时,以下划线开头的名称将不会被导入。

    【讨论】:

    • 查看 glglgl 的回答——只有在未定义 __all__ 的情况下。如果需要,您可以在 __all__ 中包含下划线前缀名称。
    【解决方案4】:

    您可以在任何变量中使用单个下划线作为第一个字符,但它具有隐含的含义,“除非您真的知道自己在做什么,否则不要在类/模块之外使用”(例如,预期受保护/internal),如果你使用from <module> import *,它不会导入。

    使用双下划线是你永远不应该在课堂之外做的事情,否则它可能会混淆名称修改(我的意思是“可能”,“过去一周让我很头疼,因为我没有意识到它确实”)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-09
      • 2020-04-11
      • 2022-11-13
      • 1970-01-01
      • 2017-03-17
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多