关于python:将self参数命名为其他内容

Naming the self parameter something else

在python中,此代码有效:

1
2
3
4
5
6
7
8
9
10
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参数是否有用?如果不是,为什么Python允许这样做,因为这当然是一种编写难以读取和维护的代码的方法,也是一种混乱的来源?


PEP8非常清楚地说明了这一点:

Always use self for the first argument to instance methods.

Always use cls for the first argument to class methods.

尽管记住,作为Python样式指南,这并不是强制的

However, know when to be inconsistent -- sometimes style guide
recommendations just aren't applicable. When in doubt, use your best
judgment. Look at other examples and decide what looks best.

有时,像在fractions.py中一样,使用a,b而不是self,other可能更清楚,因为

《样式指南》实际上列出了一些您可能会违反上述引文下面的惯例的原因:

Some other good reasons to ignore a particular guideline:

  • When applying the guideline would make the code less readable, even for someone who is used to reading code that follows this PEP.
  • To be consistent with surrounding code that also breaks it (maybe for historic reasons) -- although this is also an opportunity to clean
    up someone else's mess (in true XP style).
  • Because the code in question predates the introduction of the guideline and there is no other reason to be modifying that code.
  • When the code needs to remain compatible with older versions of Python that don't support the feature recommended by the style guide.

  • 问题的第一部分是:"是否存在这样一种情况:在这种情况下,命名自参数(self以外的东西)是有用的?"我不知道有什么真正令人信服的案例,但即使有人想出了完美的例子,它们也非常罕见,我也不会把它们当作设计选择的理由:正常使用比偶尔非故意使用self更重要。(请注意,执行名称self不会阻止任何人做任何事情;它只是一个名称。)

    那么为什么python允许这样做呢?这里有两个问题:为什么要求self明确地列在论据中(这给了我们选择另一个名字的机会),为什么不把self变成一个关键字,比如在某些其他语言中的this

    为什么它不是关键字是相当清楚的:python的设计者总是尽量减少语言中保留字的数量(在引入新语法时尽一切努力重用已经保留的字,例如,使用yield fromfrom ... importwhile ... else)。因此,如果某个东西可以合理地实现而不是保留字,那么它就是。

    一旦确定self不是关键字,而是特殊标识符,如何使其特殊?使它突然出现在每个类方法的locals()字典中会引入"魔力"行为,这也是不可取的:"显式优于隐式"。因此,self是通过在方法签名中声明引入的,唯一特殊的行为是,第一个参数绑定到我们调用的方法的对象。这使得通过修饰符支持静态和类方法变得容易,而无需为语言添加特殊的语法。(正如guido的这篇文章解释的那样,"用纯Python编写一个实现@classmethod@staticmethod)的装饰器是很简单的。"因此,一旦这种语言被设计成这样,就真的没有回头路了。


    这篇来自guido van rossum的博客文章对这个主题做了一些解释。具体来说:

    I see no reason with this proposal to make 'self' a reserved word or to require that the prefix name be exactly 'self'.

    这只是一个惯例,很高兴坚持下去。


    self参数实际上只是通过约定来命名self,这甚至不是一个普遍接受的约定——我也经常看到cls或者用这个来代替。

    在Python中,"自我"这个词不是,比如说,Java。用户可以选择给它命名任何他们想要的名字-尽管为了清晰起见,最好选择一个名字并在整个代码中坚持这个名字,但是没有任何东西阻止你在每个方法中给它命名不同的名字。