您的位置:首页 > 编程语言 > Python开发

关于Python中的self

2013-09-26 22:36 232 查看
虽然我现在写过一些Python代码,但实际上几乎还没用过Class,而且一直觉得一个很别扭的事情是,Class中的函数都要写个参数self,虽然实例化调用的时候不需要。

当然,一开始就知道Python这样设计应该有它的理由,具体是什么也没去考虑。

今天看到一个这样的说法:


源地址:http://www.douban.com/group/topic/19376685/

我解释一下python的类方法为什么要写一个self参数





来自: 巴特富莱韦杭普(Butterfly Wet-hamp) 2011-04-26 23:18:19

这是对前面一个php程序员问python方法为什么要手写一个self的回答,当时那个帖非常的热闹,但是下面没有一个回复讲到要点,等我有空,已经找不到原帖了。

原因有多重。首先是python中几乎所有的东西的一级对象(一级对象的定义:http://en.wikipedia.org/wiki/First-class_object),method也不例外,比如你写一个:
class X:
 def f(self, a, b):
  ...
那么可以这样引用f:
X.__dict__['f']
或者
X.f.__func__

现在问题来了,得到f以后怎么调用?f是一个方法,方法必须作用于对象。如果x是一个X对象,我们可以x.f(...),但是如果是以上面的方式得到的f呢?怎么f让作用于某个对象?最直观的方法就是和参数一起传递进去。

当然的限不同的设计也可以满足上面制。比如不要手写的self参数,增加this关键字,增加一个调用f个格式。这样的设计和pep20第二条不符合。

为理解python的self,不妨对比一下ruby和javascript。ruby的方式是方法不是一级对象,所以绕过了这个问题。javascript没有类,方法在调用时this会绑定到方法所属的对象,函数调用时this绑定到window,函数做构造器调用时this绑定到新对象。这么多规则,比Python复杂。

11人 喜欢 喜欢

回应 推荐 喜欢只看楼主





狼.敬畏生命 (wolf python london) 2011-04-27 08:38:50

说下我的理解:

我在学习python的时候,也发现一直写着self很别扭,在c++中,this指针是隐式的,除非不得以的时候,,比如传进来的参数和类的成员变量的名字相同,或者要返回当前对象。 而python的self是显示的。而且this指针基本上不用在函数头里面。

python是动态语言,设计出来的类和静态语言的格式不同,首先c++在类的定义(声明)时,会指定类的成员变量,比如在private:里。但是Python不行,它没法显式的说 哪个属性是自己的,而且属性还可以动态的增加,此时,一个解决方案出来了,增加self,通过self.访问的就可以做为类的属性。至于类的方法为什么要显式的写上self(我感觉,完全可以由解释器隐式添加上去),估计就是python的哲学导致的:Explicit is better than implicit.





zizi (努力赚钱中) 2011-04-27 09:20:05

个人理解:
除了前两种形式外还有第三种形式X.f,这个返回的和前两个不同。
其实你写不写self或者其他什么对于python来说都无所谓,对于python来说,方法就分两种一种是绑定的,一种是不绑定。对于绑定的方法来说,python就会把他绑定的对象作为第一个参数传给这个对象。self仅仅是提醒你这个方法会被绑定到实例上而已。

同时这样做还有个好处就是兼容python的C/API部分。Python本身是用C写成的,在C中实现类似面向机制都是这么写的:
SSL_connect(SSL *ssl, ARG *arg1)
再看看Python C API的OO部分
int PyObject_Print(PyObject *o, FILE *fp, int flags)

所以我大胆猜测self的机制是从C继承而来的。





zizi (努力赚钱中) 2011-04-27 09:26:38

PS:对于你说ruby中方法不是第一级对象这个事情能否解释一下?
我RUBY用的不多,但是我印象中ruby的方法应该能满足first class的定义。





李保银 2011-04-27 10:21:11

self是类方法的一个位置参数,它就是类的实例对象自己,当实例调用方法时:
instance = X()
instance.f('a', 'b')
等同于:
X.f(instance, 'a', 'b')
第一个参数是实例自己。

bachue 2013-05-16 15:58:28

"当然的限不同的设计也可以满足上面制。比如不要手写的self参数,增加this关键字,增加一个调用f个格式。这样的设计和pep20第二条不符合。"
不能苟同 如果真的是“Explicit is better than implicit.”,为何x.f()中的x是以implicit的方法送进f的?为何不写成f(x)?为何Python不去除面向对象以完全实现“Explicit is better than implicit.”?





alinwawa 2013-09-08 05:25:57

狼.敬畏生命,写得最好。确实python牺牲了隐式的简洁,但是换来了极大的灵活性,比如随意添加对象属性。这个比c++方便太多倍了。





苏打 2013-09-08 08:59:36

说下我的理解: 我在学习python的时候,也发现一直写着self很别扭,在c++中,this指针是隐式 ... 狼.敬畏生命
靠IDE能否省掉这些重复?





精密空调 2013-09-11 12:01:24

习惯上,方法的第一个参数命名为 self。这仅仅是一个约定:对Python而言,self 绝对没有任何特殊含义。(然而要注意的是,如果不遵守这个约定,别的Python程序员阅读你的代码时会有不便,而且有些类浏览程序也是遵循此约定开发的。)


虽然基本上算是理解了Python为什么要加这个self。但是!!!我必须想明白这个但是!!!我之所以喜欢Python,就是因为它的简洁,我之前的理解是:


用最少的工作做最多的事情

繁琐的工作没必要做

出来的结果跟想象的结果惊人的一致


正因为这样,所以,我实在是无法理解这个self,无论从哪方面考虑,它都是多余的,既然连{}这种东西都能省,为什么一个self不能省?!纵使PEP 20哲学说清晰好过模糊,但为什么还支持带缺省值的参数,为什么不像C语言那样不能省略?

所以,无论是从Python设计哲学还是设计技术细节来考虑,这个self真的是一个很奇怪的东西,再怎么说,前面已经有个class了,这一段就是类啊!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: