【问题标题】:Python: class with double underscorePython:带有双下划线的类
【发布时间】:2016-12-03 09:45:50
【问题描述】:

我正在关注link 并尝试使用 Metaclass 创建一个单例类。但是,我想对这个单例类进行一些内部调整,并希望用户使用另一个类(我们称之为MySingleton(__Singleton))。所以我决定将其设为私有,但它给出了以下错误。

我唯一的目的是防止__Singleton被外部使用。我怎样才能做到这一点?

另外,在类中使用双下划线是一种好习惯吗?

【问题讨论】:

  • 你想防止__Singleton在什么之外被使用?
  • 在我的模块之外。只有MySingleton 可供任何想要使用它的人访问。
  • 前导双下划线不是通用的隐私标记。它们不会使事情比单个下划线更私密。
  • 基本上,名称被破坏了。所以,使用它的摩擦更大。

标签: python python-2.7 class private


【解决方案1】:

类定义中带有两个前导下划线的每个名称都被破坏,因此__Singleton 变为_Singleton__Singleton。为了清楚起见,某些类不应该公开使用一个下划线。

【讨论】:

  • 即使_Singleton__Singleton 也不起作用。试试看
  • 你真的试过class _Singleton__Singleton(type): ...吗?
【解决方案2】:

在类内部,标识符__Singleton 正在获取mangled。你最终会遇到问题,因为名称修改只发生在类内部(而不是外部)。所以__Singleton 作为一个类名,当你在一个类套件中时,它的含义与__Singleton 不同。

__spam 形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为 _classname__spam,其中类名是当前类名,前导下划线被去除。 只要它出现在类的定义中,就无需考虑标识符的句法位置。

请注意,修改的主要原因是因为它

...有助于让子类覆盖方法而不破坏类内方法调用。

还有:

...避免名称与子类定义的名称发生名称冲突

因此,实际上没有任何理由在名称中包含前导双下划线的类(类内方法调用不可能与类名发生冲突)。单个前导下划线足以向用户表明他们不应使用该类:

... 带有下划线前缀的名称(例如_spam)应被视为 API 的非公共部分(无论是函数、方法还是数据成员)。 应视为实施细节,如有更改,恕不另行通知。


我不建议这样做,但如果您真的希望它工作,您可能可以使用globals 来查找课程:

class __Foo(object):
    def __init__(self):
        super(globals()['__Foo'], self).__init__()

f = __Foo()
print f

【讨论】:

  • 为什么不可取?
  • @PankajSinghal -- 大量额外的输入和奇怪的(有点混乱和低效)的内省绝对没有收获......
【解决方案3】:

Python 没有private variables;它们都可以从外部访问。

在 Python 中不存在只能从对象内部访问的“私有”实例变量。但是,大多数 Python 代码都遵循一个约定:前缀为下划线的名称(例如 _spam)应被视为 API 的非公共部分(无论是函数、方法还是数据成员) .它应被视为实现细节,如有更改,恕不另行通知。

Python Cookbook 提供了一个Singleton class,可以被其他类继承成为Singletons。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-09
    • 2018-06-30
    • 2011-10-19
    • 2021-11-28
    • 2012-11-09
    • 2019-06-23
    相关资源
    最近更新 更多