【问题标题】:Naming the self parameter something else将 self 参数命名为其他名称
【发布时间】:2016-10-19 12:19:51
【问题描述】:

在 Python 中,此代码有效:

class A:

    def __init__(me):
        me.foo = 17

    def print_foo(myself):
        print(myself.foo)

    def set_foo(i, v):
        i.foo = v

您可能已经注意到,self 参数在 __init__ 方法中命名为 me,在 print_foo 方法中命名为 myself,在 set_foo 方法中命名为 i

是否存在将self 参数命名为self 以外的名称有用的情况?如果不是,为什么 Python 允许这样做,因为它肯定是编写难以阅读和维护的代码的一种方式,也是混乱的根源?

【问题讨论】:

  • 因为PEP-20“显式优于隐式”,因此您不希望出现一个神奇的self,并且“特殊情况不足以打破规则”,所以如果它是一个显式参数,你可以给它分配任何你喜欢的名字。
  • “如果不是,为什么 Python 允许这样做”,因为 不允许 允许它是一个非常愚蠢的限制。
  • "为什么 Python 允许这样做" 那么为什么要停在那里呢?我还可以创建一个名称为subtract 的函数,它将两个数字相加。这也会造成混乱,但 Python 允许这样做。
  • 单个函数可以作为实例方法也可以作为类方法,这就排除了在首次定义函数时需要特定名称。 class A: pass; def foo(first): pass; A.inst = foo; A.cls = classmethod(foo) 创建一个具有(平凡的)实例和使用相同底层函数对象实现的类方法的类。

标签: python self


【解决方案1】:

PEP 8 addresses this pretty clearly:

始终使用self 作为实例方法的第一个参数。

始终使用cls 作为类方法的第一个参数。

虽然记得是蟒蛇style guide this is not enforced

但是,知道什么时候不一致——有时是风格指南 建议只是不适用。如有疑问,请尽力而为 判断。看看其他例子,然后决定什么看起来最好。

有时,like in fractions.py in the standard library,您可能更清楚使用a,b 之类的东西而不是self,other,因为<your specific reasons>

样式指南实际上列出了一些您可能会在上述引用下方打破常规的原因:

忽略特定准则的其他一些充分理由:

  1. 如果应用该指南会降低代码的可读性,即使对于习惯阅读遵循此 PEP 的代码的人也是如此。
  2. 为了与也破坏它的周围代码保持一致(可能是出于历史原因)——尽管这也是一个清理的机会 搞砸别人的烂摊子(真正的 XP 风格)。
  3. 因为有问题的代码早于指南的引入,并且没有其他理由修改该代码。
  4. 当代码需要与不支持样式指南推荐的功能的旧版 Python 保持兼容时。

【讨论】:

    【解决方案2】:

    您问题的第一部分是:“是否存在将 self 参数命名为 self 以外的其他名称的情况?”我不知道有什么真正令人信服的案例,但即使有人提出了完美的例子,它们也非常罕见,我不会将它们视为这种设计选择的原因:正常使用远比偶尔不得不以不直观的方式使用self。 (请注意,强制使用名称 self 不会阻止任何人完成任何事情;它只是一个名称。)

    那么为什么 python 允许这样做呢?这里有两个问题:为什么需要在参数中明确列出self(这使我们有机会选择另一个名称),以及为什么不将self 变成关键字,例如某些其他语言中的this

    为什么它不是关键字很清楚:python 的设计者总是尽量减少语言中保留字的数量(以至于在引入新语法时尽一切努力重用已经保留的字,例如 @ 987654327@、from ... importwhile ... else)。因此,如果某些东西可以在没有保留字的情况下合理地实现,那就是。

    一旦确定self 不是关键字,而是一个特殊的标识符,你如何让它变得特别?让它突然出现在每个类方法的locals() 字典中会引入再次不受欢迎的“魔术”行为:“显式优于隐式”。因此,self 是通过在方法签名中声明来引入的,唯一的特殊行为是第一个参数绑定到我们调用其方法的对象。这使得通过装饰器支持静态和类方法变得容易,而无需向语言添加特殊语法。 (正如 Guido 的 this post 解释的那样,“编写一个在纯 Python 中实现 @classmethod@staticmethod 的装饰器是微不足道的。”)因此,一旦以这种方式设计语言,就真的没有回头路了。

    【讨论】:

      【解决方案3】:

      Guido van Rossum 的This blog post 围绕这个主题做了一些解释。特别是:

      我认为这个提议没有任何理由让“self”成为保留字或要求前缀名称完全是“self”。

      这只是一个约定,坚持下去很好。

      【讨论】:

        【解决方案4】:

        self 参数实际上只是按照约定命名为 self,这甚至不是普遍接受的约定 - 我也经常看到 clsthis 改为使用。

        self 一词在 python 中并不是一个关键字,就像在 Java 中那样。用户可以选择任何他们想要的名称 - 尽管为了清晰起见,最好选择一个名称并在整个代码中坚持使用该名称,但没有什么会阻止您在每种方法中命名不同的名称。

        【讨论】:

        • 请注意,您会看到cls,其中第一个参数是类而不是实例(参见例如stackoverflow.com/q/4613000/3001761),而this 编写代码的人是一个怪物。 “这甚至不是一个普遍接受的约定” - 它是in the official style guide 等等。
        • 详细来说,正如self是实例方法第一个参数的命名约定一样,cls是类方法第一个参数的命名约定。
        猜你喜欢
        • 2014-11-26
        • 1970-01-01
        • 2020-01-14
        • 1970-01-01
        • 1970-01-01
        • 2021-05-13
        • 2021-01-08
        • 2022-07-06
        • 2021-08-27
        相关资源
        最近更新 更多