zoukankan      html  css  js  c++  java
  • 为什么Python定义的class中的函数需要self作为第一个参数

    Why must ‘self’ be used explicitly in method definitions and calls?

      The idea was borrowed from Modula-3. It turns out to be very useful, for a variety of reasons.

      First, it’s more obvious that you are using a method or instance attribute instead of a local variable. Reading self.x or self.meth() makes it absolutely clear that an instance variable or method is used even if you don’t know the class definition by heart. In C++, you can sort of tell by the lack of a local variable declaration (assuming globals are rare or easily recognizable) – but in Python, there are no local variable declarations, so you’d have to look up the class definition to be sure. Some C++ and Java coding standards call for instance attributes to have an m_ prefix, so this explicitness is still useful in those languages, too.

      Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the :: operator – in Python you can write baseclass.methodname(self, <argument list>). This is particularly useful for __init__() methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow.

      Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a value is assigned in a function body (and that aren’t explicitly declared global), there has to be some way to tell the interpreter that an assignment was meant to assign to an instance variable instead of to a local variable, and it should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn’t have declarations and it would be a pity having to introduce them just for this purpose. Using the explicit self.var solves this nicely. Similarly, for using instance variables, having to write self.var means that references to unqualified names inside a method don’t have to search the instance’s directories. To put it another way, local variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use.

    中文翻译(原创):

      这种做法是借鉴自Modula-3, 在很多方面来看到都是很有用的。
      首先,让你很明显看出这是在使用一个实例方法或属性,而不是一个局部变量

          即便对类的定义不清楚,遇到self.x或者self.meth()都会明白这是实例属性或方法。

    在C++中,如果局部变量未声明,编译器会告诉你;但是,在python中,由于局部变量不需要声明,
    使得你需要在类的定义中去找。一些C++及Java的编码规范需要使用m_做前缀来定义实例属性,在这些语言中,这种明确的
    定义是非常有用的。

      其次,这样做可以不需要特别的语法,来供一个class去调用这些方法

         在C++中,如果你想在子类中调用基类中被那些被子类复写的方法,

    你需要使用::操作符 - 在Python中,你可以使用baseclass.methodname(self, <argument list>)的
    方式来调用,这对于__init__()方法特别有用,另外对于子类中复写的方法想要调用基类中同名方法时也非常有效。

      最后,属性解决了赋值的语法问题

         因为python中的局部变量都是在函数体中被赋值的(它们没有被定义成全局变量),
    需要有一种方式来告诉解释器某一个赋值操作是赋给属性还是局部变量,这样可以更好地语法检查(为了高效)。C++通过声明
    来做到这一点,但是Python没有声明,为此而引入声明也不划算。明确地使用self.var可以很好地解决这个问题。
    使用self.var意味着:在一个方法中引用一个非法的变量不需要在实例目录中去查找(这一部分不太能够理解)。另外,局部
    变量和实例变量存在于不同的命名空间,你需要告诉python到底应该使用哪个命名空间。

    参考: http://docs.python.org/2/faq/design.html#why-must-self-be-used-explicitly-in-method-definitions-and-calls

  • 相关阅读:
    Spring MVC 拦截器
    spring中MultiActionController的数据绑定
    Hibernate多对多配置
    hibernate实体类配置文件问题(字段使用默认值)
    HibernateTemplate类的使用 (转)
    javascript小笔记(一)
    spring整合hibernate(2)
    Sina AppEngine 的bug
    找工作
    天下武功唯快不破
  • 原文地址:https://www.cnblogs.com/Ice-Max/p/3376657.html
Copyright © 2011-2022 走看看