Perché hai bisogno di "self" in Python per fare riferimento alle variabili di istanza?

10

Ho programmato in un certo numero di lingue come Java, Ruby, Haskell e Python. Devo passare da molte lingue al giorno a causa di diversi progetti su cui lavoro. Ora, il problema è che spesso mi dimentico di scrivere self come il primo parametro nelle definizioni di funzione in Python stesso con i metodi di chiamata sullo stesso oggetto.

Detto questo, sono abbastanza sorpreso da questo approccio di Python. Fondamentalmente dobbiamo digitare di più per fare le cose, nei linguaggi come Java e Ruby le cose sono rese semplici facendo riferimento automaticamente alle variabili nell'oggetto corrente.

La mia domanda è: perché è necessario questo self ? È puramente una scelta di stile, o c'è una ragione per cui Python non può lasciarti omettere self come Java e C ++ ti lasciano omettere this ?

    
posta vivek 20.11.2015 - 06:41
fonte

3 risposte

18

1) Perché è richiesto self come parametro esplicito nelle firme dei metodi?

Poiché i metodi sono funzioni e foo.bar(baz) è solo zucchero sintattico per bar(foo, baz) . Le classi sono solo dizionari in cui alcuni dei valori sono funzioni. (I costruttori sono anche solo funzioni, ed è per questo che Python non ha bisogno di new ). Si può dire che Python rende esplicito che gli oggetti sono costruiti con componenti più semplici. Questo è in accordo con la filosofia "esplicita è meglio che implicita".

Al contrario, negli oggetti Java sono davvero magici e non possono essere ridotti a componenti più semplici nella lingua. In Java (almeno fino a Java 8) una funzione è sempre un metodo di proprietà di un oggetto e questa proprietà non può essere modificata a causa della natura statica della lingua. Pertanto non vi è alcuna ambiguità su cosa si riferisca a this , quindi ha senso averlo implicitamente definito.

JavaScript è un esempio di un linguaggio che ha un% implicito come% di Java, ma in cui le funzioni possono esistere separatamente da oggetti come in Python. Questo porta a un sacco di confusione su cosa this fa riferimento quando le funzioni vengono passate e chiamate in diversi contesti. Molti pensano istintivamente che this debba riferirsi a qualche proprietà intrinseca della funzione, mentre in realtà è determinata esclusivamente dal modo in cui viene chiamata la funzione. Credo che avere this come parametro esplicito come in Python renderebbe molto meno confuso.

Alcuni altri vantaggi del parametro this -parametro esplicito:

  • I decoratori sono solo funzioni che racchiudono altre funzioni. Poiché i metodi sono solo funzioni, i decoratori funzionano altrettanto bene sui metodi. Se ci fosse un qualche tipo di sé implicito, i decoratori non lavorerebbero in modo trasparente sui metodi.

  • I metodi di classe e i metodi statici non accettano un parametro di istanza. Classmethods accetta una classe come primo argomento (in genere chiamato self ). I parametri espliciti cls o self rendono molto più chiaro cosa sta succedendo e a cosa hai accesso nel metodo.

2) Perché le variabili istanze devono sempre essere qualificate con " cls ?

In Java, non è necessario prefisso le variabili membro con " self. ", ma in Python " this. " è sempre richiesto. La ragione è che Python non ha una sintassi esplicita per dichiarare le variabili, quindi non ci sarebbe modo di dire se self. dovrebbe dichiarare una nuova variabile locale o assegnarla a una variabile membro. Specificando x = 7 risolvi questa ambiguità.

    
risposta data 20.11.2015 - 08:43
fonte
6

C'è una ragione piuttosto semplice per cui AFAIK non è stato realmente toccato nel duplicato cross-site, né qui: Python ha iniziato come linguaggio procedurale. Era basato su ABC, anche un linguaggio procedurale.

L'Object-Orientation è stato aggiunto più tardi, e quando è stato aggiunto, Guido van Rossum voleva aggiungere la minima quantità di funzionalità possibili, al fine di mantenere semplice il design di Python. Python aveva già dict s e funzioni, quindi perché aggiungere qualcosa di completamente nuovo al linguaggio, quando un oggetto può semplicemente essere un dict di slot e una classe può essere semplicemente una dict di funzioni? Un metodo può essere interpretato come una funzione parzialmente applicata che si chiude su un singolo argomento distinto. Ed è proprio come i metodi sono implementati in Python: non lo sono. Sono solo funzioni che ricevono un argomento distinto in più.

    
risposta data 20.11.2015 - 11:58
fonte
1

Ecco le mie conclusioni basate sulle risposte precedenti e sulla lettura del di Guido stesso. vagante su questo argomento:

La grande idea

Le funzioni sono gli elementi costitutivi importanti in Python (o dovremmo dire l'unico), in effetti stiamo emulando OOP usando le funzioni.

Dato che una classe non è altro che un dizionario di funzioni, possiamo allegare qualsiasi funzione a qualsiasi classe in fase di esecuzione. Fondamentalmente è a causa di questa necessità di lanciare le funzioni in fase di esecuzione, possiamo fare cose come Monkey Patching . Qui il parametro self supporta il Polymorphism parametrico.

    
risposta data 21.11.2015 - 08:53
fonte