程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Why does Python keep explicit self?

編輯:Python

Bruce Proposal
Bruce know , We need a way to distinguish references to instance variables from references to other variables , So he suggested that “self” Set as keyword .
Consider a typical class , It has a way , for example :

class C:
def meth(self, arg):
self.val = arg
return self.val

Follow up Bruce Proposal , This will become :

class C:
def meth(arg):# Look ma, no self!
self.val = arg
return self.val

This saves each method 6 Characters . But I don't think Bruce This suggestion is made to reduce typing .
I think what he really cares about is programmers ( May be from another language ) Wasted time , Sometimes it seems that there is no need to specify “self” Parameters , And they sometimes forget to add ( Even if they know it —— Habit is a powerful force ). exactly , And forget to type before instance variables or method references “self.” comparison , Omit from parameter list “self”, Often leads to very vague error messages .

Maybe even worse ( Such as Bruce Described ), When the method is declared correctly , But the number of parameters in the call is not right , Error message received at this time . Such as Bruce The following examples are given :

Traceback (most recent call last):
File "classes.py", line 9, in
obj.m2(1)
TypeError: m2() takes exactly 3 arguments (2 given)

I agree that it's confusing , But I would rather solve the error message , Instead of changing the language .

Why? Bruce 's proposal is not feasible
First , Let me put forward some suggestions Bruce The opposite typical argument .
There is a good argument for , Use explicit... In the parameter list “self”, You can enhance the theoretical equivalence of the following two call methods . hypothesis “ foo” yes “C” An example of :
foo.meth(arg) == C.meth(foo, arg)
( Translation notes : Tell the truth , I don't understand the meaning of this example . Here's just my opinion . When defining methods inside a class , There may be several different ways : Example method 、 Class methods and Static methods . Their function and behavior are different , So how to distinguish between definition and call ?Python Agreed on a way , That is, the first parameter is used to distinguish :self Represent instance method 、cls Or other symbols Represent class methods …… All three methods can be called by an instance of a class , And it looks as like as two peas. , As in the example above, on the left side of the equal sign . In this case, it depends on the parameters given in the definition to distinguish , Like the right side of the equal sign above , The first parameter is the instance object , It shows that this is an example method .)
Another argument is , Use explicit... In the parameter list “self”, Insert a function into a class , Gain the ability to dynamically modify a class , Create a corresponding class method .
for example , We can create one with the above “C” Completely equivalent class , As shown below :

# Define an empty class:
class C:
pass
# Define a global function:
def meth(myself, arg):
myself.val = arg
return myself.val
# Poke the method into the class:
C.meth = meth

Please note that , I will “self” Rename parameter to “myself”, To emphasize ( In grammar ) We are not defining a method here ( Translation notes : Outside the class are functions , namely function, Inside the class are methods , namely method).

After this ,C The instance of has a “meth” Method , This method has one parameter , And the function is exactly the same as before . For those created before the method is inserted into the class C Example , It even works .

I think Bruce Not particularly concerned about the equivalence of the above . I agree that it's only theoretically important . The only exception I can think of is the old idiom for calling super methods (idiom). however , This idiom is easy to make mistakes ( It's because of the need to explicitly pass "self" Why ), Is that why Python 3000 in , I suggest using... In all cases "super()" Why .

Bruce You might think of a way to make the second equivalent work —— In some cases , This equivalence is really important . I don't know Bruce How much time did it take to think about how to implement his proposal , But I think he's thinking about calling one “self” The extra parameters of are automatically added to all methods defined directly inside the class ( I have to say yes “ directly ”, So that functions nested inside methods , Free from this automatic operation ). such , You can make the first equivalent equal .

however , There's a situation I think Bruce You can't add something... Without adding it to the compiler ESP In case of : Decorator . I believe this is Bruce The final failure of the proposal .

When decorating a method , We don't know if we want to automatically add a “self” Parameters : A decorator can turn a function into a static method ( No, “self”) Or a class method ( There's an interesting one self, It points to a class rather than an instance ), Or you can do something totally different ( In pure Python Realization “ @classmethod” or “ @staticmethod” The decorators are tedious ). Unless you know the purpose of the decorator , Otherwise, there is no other way to determine whether to give the method being defined an implicit “self” Parameters .

I refuse things like special packing “@classmethod” and “@staticmethod” Black technology like that . I also think that in addition to self inspection , Automatically determine that a method is a class method (class method)、 Example method (instance method) Or static method (static method), It's not a good idea ( As in the Bruce In the comments of , It was suggested ): This makes it difficult to just follow the method before “def”, To decide how the method should be called .

( Translation notes : For a method , In the current case of adding corresponding parameters , You can simply add a decorator , Distinguish which method it is , It's also easy to distinguish calls ; however , If no parameter is added , Even if it's possible to use a magic automatic mechanism to distinguish which way it is , But when called , You're not sure how to call ).

In commentary , I see some very extreme right Bruce Of the proposal , But the usual cost is making the rules hard to follow , Or ask for deeper changes to the language , This makes it extremely difficult for us to accept it , Especially the integration Python 3.1. By the way , about 3.1, Declare our rules again , New features are only acceptable if they are backward compatible .

There is a suggestion that seems to work ( Can make it backward compatible ) It's in the class
def foo(self, arg): ...
Change it to this kind of grammar sugar :
def self.foo(arg): ...
But I don't agree with it “self” Change to reserved word (reserved word), Or the prefix must be “self”. If this is done , So for class methods , It's easy to see that too :

@classmethod
def cls.foo(arg): ...

Okay , Compared with the current situation , I didn't like this better . But compared to Bruce In the comments section of his blog , I think this is much better , And it has a huge advantage of backward compatibility , And it doesn't take much effort , It can be written as a reference implementation PEP.( I think Bruce You should find flaws in your proposal , If he really tries to write reliable PEP Or try to implement it .)
I can keep talking a lot , But it was a sunny Sunday morning , And I have other plans ... :-)

The above is all the content shared this time , Want to know more python Welcome to official account :Python Programming learning circle , send out “J” Free access to , Daily dry goods sharing


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved