gpt4 book ai didi

python - Python 类名中的前导下划线

转载 作者:太空狗 更新时间:2023-10-29 16:57:52 26 4
gpt4 key购买 nike

此问题基于 this one asked earlier还有this one ,但解决了一个更微妙的问题,具体来说,什么才算是“内部类”?

这是我的情况。我正在构建一个用于操作 MS Office 文件的 Python 库,其中许多类并不打算在外部构建,但它们的许多方法都是 API 的重要部分。例如:

class _Slide(object):
def add_shape(self):
...

_Slide 不能在外部构造,作为库的最终用户,您可以通过调用 Presentation.add_slide() 获得一张新幻灯片。但是,一旦有了幻灯片,您肯定希望能够调用 add_shape()。所以该方法是 API 的一部分,但构造函数不是。这种情况在库中出现了数十次,因为只有 Presentation 类具有外部/API 构造函数。

PEP8 在这一点上模棱两可,提到了“内部类”,但没有详细说明什么才算是内部类。在这种情况下,我想可以说这个类是“部分内部的”。

问题是我只有两个符号来区分至少三种不同的情况:

  1. 类的构造函数和“public/API”方法都可以使用。
  2. 不使用构造函数,但使用类的“public/API”方法。
  3. 该类确实是内部类,没有公共(public) API,我保留在未来版本中更改或删除它的权利。

我注意到,从通信的角度来看,外部 API(图书馆最终用户受众)和内部 API(开发人员受众)的明确表达之间存在冲突。对于最终用户,调用 _Slide() 是禁止的/自担风险。然而,它是内部 API 的一个快乐成员,并且与 _random_helper_method() 不同,后者只能从 _Slide() 中调用。

你对这个问题有什么观点可以帮助我吗?惯例是否规定我在类名上使用我的“单前导下划线”弹药以争取最终用户 API 的清晰度,或者我是否可以保留它以与我自己和其他开发人员沟通类 API 何时真正私有(private)且不被使用,例如,由它所在的模块外部的对象使用,因为它是一个可能更改的实现细节?


更新:经过几年的进一步思考,我已经习惯了在命名不打算作为类访问的类时使用前导下划线的约定作为一个类 在他们的模块(文件)之外。这种访问通常是实例化该类的对象或访问类方法等。

这为模块的用户(当然通常是您自己 :) 提供了基本指示器:“如果带有前导下划线的类名出现在导入语句中,则说明您做错了。” (单元测试模块是此规则的一个异常(exception),此类导入可能经常出现在“内部”类的单元测试中。)

请注意,这是对 的访问。访问模块外部该类(类型)的对象(可能由工厂或其他任何方式提供)是完全没问题的,而且可能是预期的。我认为这种未能区分类和由类创建的对象是导致我最初感到困惑的原因。

这个约定还有一个附带的好处,就是在执行 from module import * 语句时不包括这些类。尽管我从不在自己的代码中使用它们并建议避免使用它们,但这是一种适当的行为,因为这些类标识符不打算成为模块接口(interface)的一部分。

这是我个人经过多年试验得出的“最佳实践”,当然不是“正确”的方法。您的里程可能会有所不同。

最佳答案

我无法仅根据您问题中的描述判断,但根据您在评论中提供的其他信息,我认为您的 Slide 类实际上是公开的。

尽管实例只会通过调用 Presentationadd_slide() 方法间接创建,但这是正确的,因为调用者随后将空闲(以及更多可能需要)调用实例的方法以在之后对其进行操作。在我看来,一个真正的私有(private)类只能被“拥有”它的类的方法访问。

让事情成为任何其他方式既会破坏封装又会增加设计组件之间的耦合,这两者都是不可取的,为了灵 active 和可重用性应尽可能避免。

关于python - Python 类名中的前导下划线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18540371/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com