你为什么需要“自我”。在Python中引用实例变量?


13

我一直在编程多种语言,例如Java,Ruby,Haskell和Python。由于我从事的项目不同,我每天必须在多种语言之间切换。现在,问题是我常常忘记写代码,self因为Python中函数定义中的第一个参数与在同一对象上调用方法相同。

也就是说,我对Python的这种方法感到惊讶。基本上,我们必须键入更多内容才能完成工作,在Java和Ruby之类的语言中,通过自动引用当前对象中的变量使事情变得简单。

我的问题是为什么这是self必要的?纯粹是样式选择,还是有原因导致Python不能让您忽略selfJava和C ++的想法this



1
@gnat现在仅是专业人士,并且认真地对待它是一个好问题,自几天以来一直困扰着我,请不要投票否决它。
vivek

2
stackoverflow.com/questions/2709821/…已彻底解决了这个问题。
David Arno

我的理解是,它基于C风格,即将指向结构的指针作为第一个参数传递给C。
Dannnno

@staticmethod在方法声明之前编写,可以抑制错误(仅用于提供信息,也不建议使用)
Yash

Answers:


23

1)为什么self在方法签名中要求它作为显式参数?

因为方法是函数,foo.bar(baz)只是语法糖bar(foo, baz)。类只是其中一些值是函数的字典。(构造函数也只是函数,这就是Python不需要的原因。new)您可以说Python明确表明对象是由更简单的组件构建的。这符合“显性胜于隐性”的哲学。

相反,在Java中,对象确实是魔术,不能用语言简化为简单的组件。在Java中(至少在Java 8之前),函数始终是对象拥有的方法,并且由于语言的静态性质,因此无法更改此所有权。因此,对于this所指的内容没有任何歧义,因此对其进行隐式定义是有意义的。

JavaScript是具有隐式语言(this例如Java)的语言的示例,但其中的功能可以与对象(例如Python)分开存在。对于在不同上下文中传递和调用函数时所指的内容,这引起很多困惑this。许多本能地认为this必须引用函数的某些内在属性,而实际上它完全是由调用函数的方式确定的。我相信this像Python那样具有显式参数可以减少混乱。

显式- self参数的其他一些好处:

  • 装饰器只是包装其他功能的功能。由于方法只是函数,所以装饰器在方法上也可以正常工作。如果存在某种隐式的自身,则装饰器将无法在方法上透明地工作。

  • 类方法和静态方法不使用实例参数。Classmethods采取作为第一个参数(通常称为cls)。显式selfcls参数使您可以更清楚地了解正在发生的事情以及您可以在该方法中访问的内容。

2)为什么实例变量必须总是用“”限定self.

在Java中,您不需要在成员变量前添加“ this.” 作为前缀,但在Python self.中,始终需要“ ”。原因是Python没有用于声明变量的显式语法,因此无法得知x = 7是应该声明新的局部变量还是将其分配给成员变量。指定self.解决了这种歧义。


隐式成员变量引用(没有self.Java一样)与范围规则根本不兼容,并且当您需要在此范围内显式时,对参数隐式不再有太多意义。
Jan Hudec

@JanHudec:好,要点。我已将其添加到答案中。
JacquesB,2015年

6

有一个很简单的原因,即跨站点副本中并未真正涉及到AFAIK,也没有在这里涉及到:Python最初是一种过程语言。它基于ABC,也是一种程序语言。

后来添加了面向对象,当添加时,Guido van Rossum希望添加尽可能少的功能,以使Python的设计保持简单。Python已经有了dicts和函数,那么当一个对象可以只是一个dict插槽,而一个类可以是一个函数时,为什么还要在语言中添加一些全新的东西dict呢?方法可以解释为部分应用的函数,该函数在单个专有参数上封闭。这正是在Python中实现方法的方式:实际上并非如此。它们只是接收额外引人注目的参数的函数。


我相信Python支持OO,并具有从第一个发行版本开始的类和继承。至少这是维基百科告诉我的。但是van Rossums最初设计语言的过程可能与您描述的一样。
JacquesB 2015年


谢谢您的链接,这真的很有趣。
JacquesB 2015年

2

这是我根据上述答案得出的结论,并阅读了Guido 对此主题的漫谈

好主意

函数是Python中重要的构建块(或者我们应该说唯一的一个),实际上,我们通过使用函数来模拟OOP。

鉴于类不过是函数字典,因此,我们可以在运行时将任何函数附加到任何类。基本上是因为需要在运行时抛弃函数,所以我们可以做诸如Monkey Patching之类的事情。这里的self参数支持参数多态性。


1
当您的答案是高质量答案时,鼓励您回答自已的问题 当我在这里将您的答案与其他答案进行比较时,我想知道为什么您觉得需要添加它。其他答案比您的答案更深入,更详细。

1
@ GlenH7的答案仅供参考,因为每次我都无法一次又一次地阅读每个人的答案时。关于质量,请告诉我是否有任何信息令人误解。无论如何,我通常要等待2-3天才能接受任何答案。
vivek

向下投票已成为一种廉价货币,这里的每个人都在不知其含义的情况下双手花钱。您是否意识到如果有人来到这里看到这个答案被否决会认为它是错误的!
vivek
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.