Ein bisschen mehr über Referenzen ~ Verwenden von Python und Java als Beispiele ~

Einführung

Beachten Sie, dass der Artikel "Über Python-Referenz" interessant war. In diesem Artikel,

Als ich mit Python anfing, stieß ich als erstes auf die mysteriöse Erklärung, die oft überall zu sehen ist: "Alle Python-Argumente werden als Referenz übergeben."

Es gab eine Passage. Wie bereits in den Kommentaren erwähnt, werden "alle Python-Argumente als Referenz übergeben", aber es scheint, dass es in Python keinen Wertübergang gibt! Ich habe einen Artikel "Übergeben von Wert, Übergeben von Referenz, Übergeben von Referenz" mit fast demselben Thema geschrieben, in dem Ganzzahlen und Gleitkommazahlen enthalten sind Ich habe geschrieben, dass die Zahl in Python als Wert übergeben wird. In der Tat gab das eine konsequente Erklärung und den Originalartikel

Wenn ein neues Objekt selbst einer Variablen zugewiesen wird, bezieht es sich auf den Ort, an dem das neue Objekt erstellt wurde, anstelle des vorherigen Referenzziels.

Dieser Teil ist der gleiche wie der, den ich in der Erklärung zum Übergeben von Referenzen nach Wert geschrieben habe. Ich habe mir jedoch die Kommentare angesehen und möglicherweise etwas Ungenaues geschrieben, sodass ich es eingehend untersucht habe.

Ganzzahliges Verhalten in Python und C ++

Betrachten Sie den folgenden Python-Code.

ex1.py


a = 1
b = a
print("a : value = " + str(a) + "\tid = " + str(id(a)))
print("b : value = " + str(b) + "\tid = " + str(id(b)))
a : value = 1	id = 4360526320
b : value = 1	id = 4360526320

Dies ist sicherlich "Referenzübergabe", nicht "Wertübergabe". Denn wenn Sie einen Wert übergeben, sollte id (Zeigerwert) nicht wie das folgende C ++ übereinstimmen.

ex1.cpp


#include <iostream>

int main(){
    int a = 1;
    int b = a;
    std::cout << "a : value = " << a << "\tid = " << &a << "\n";
    std::cout << "b : value = " << b << "\tid = " << &b << "\n";
    return 0;    
}
a : value = 1	id = 0x7fff50360ae8
b : value = 1	id = 0x7fff50360ae4

Was ist, wenn dies als nächstes passiert?

ex2.py


a = 1
b = a
print("a : value = " + str(a) + "\tid = " + str(id(a)))
print("b : value = " + str(b) + "\tid = " + str(id(b)) + "\n")

b = 2
print("a : value = " + str(a) + "\tid = " + str(id(a)))
print("b : value = " + str(b) + "\tid = " + str(id(b)))
a : value = 1	id = 4348889584
b : value = 1	id = 4348889584

a : value = 1	id = 4348889584
b : value = 2	id = 4348889616

ex2.cpp


#include <iostream>

int main(){
    int a = 1;
    int b = a;
    std::cout << "a : value = " << a << "\tid = " << &a << "\n";
    std::cout << "b : value = " << b << "\tid = " << &b << "\n\n";
    
    b = 2;
    std::cout << "a : value = " << a << "\tid = " << &a << "\n";
    std::cout << "b : value = " << b << "\tid = " << &b << "\n";
    return 0;
}
a : value = 1	id = 0x7fff561cdae8
b : value = 1	id = 0x7fff561cdae4

a : value = 1	id = 0x7fff561cdae8
b : value = 2	id = 0x7fff561cdae4

Auf diese Weise ändert sich in Python im Gegensatz zu C ++ auch die ID, wenn Sie einen anderen Wert zuweisen. Mit anderen Worten, das Referenzziel ändert sich. Was ist mit zusammengesetzten Zuweisungen wie + =?

ex3.py


a = 1
b = a
print("a : value = " + str(a) + "\tid = " + str(id(a)))
print("b : value = " + str(b) + "\tid = " + str(id(b)) + "\n")

b += 2
print("a : value = " + str(a) + "\tid = " + str(id(a)))
print("b : value = " + str(b) + "\tid = " + str(id(b)))
a : value = 1	id = 4507830768
b : value = 1	id = 4507830768

a : value = 1	id = 4507830768
b : value = 3	id = 4507830832

Das ist das gleiche. Wie Sie im Kommentar des Originalartikels sehen können, heißt "b + = 2" tatsächlich "b = b + 2", und es wird auch eine neue Referenz zugewiesen. Mit anderen Worten, in Python: "Jedes Mal, wenn Sie den Wert einer Ganzzahl ändern, wird ein neues Objekt im Speicher erstellt und zugewiesen, sodass sich auch die ID ändert." Mit anderen Worten, in Python heißt es: "Sobald Sie eine Ganzzahl im Speicher generiert haben, können Sie sie nicht mehr ändern", was als "** unveränderlich " bezeichnet wird. Das Gegenteil ist " veränderlich **". Andere unveränderliche Typen sind Gleitkommazahlen, Bourians, Strings, Taples und None. Was in Python wichtig ist, ist "veränderlich oder nicht" und nicht "Übergeben von Werten". Es wird sein. Ich wusste es nicht.

Java-String- und Wrapper-Klasse

Java hat übrigens etwas Ähnliches wie das obige Python-Beispiel. Wrapper-Klassen wie String und Integer und Double.

Ex1.java


class Ex1{
    public static void main(String[] args){
        String s1 = "foo";
        String s2 = s1;
        System.out.println("s1 : " + s1);
        System.out.println("s2 : " + s2 + "\n");
        
        s2 += "bar";
        System.out.println("s1 : " + s1);
        System.out.println("s2 : " + s2 + "\n");

        Integer i1 = 1;
        Integer i2 = i1;
        System.out.println("i1 : " + i1);
        System.out.println("i2 : " + i2 + "\n");
        
        i2 += 2;
        System.out.println("i1 : " + i1);
        System.out.println("i2 : " + i2);
    }
}
s1 : foo
s2 : foo

s1 : foo
s2 : foobar

i1 : 1
i2 : 1

i1 : 1
i2 : 3

Auf diese Weise verhalten sich Java-Zeichenfolgen und Ganzzahlen wie Referenzübergaben, obwohl sie Referenztypen sind. Versuchen wir, die Klassendatei zu dekompilieren, die durch Kompilieren der obigen Datei mit jad erstellt wurde.

Ex1.jad


// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Ex1.java

import java.io.PrintStream;

class Ex1
{

    Ex1()
    {
    }

    public static void main(String args[])
    {
        String s = "foo";
        String s1 = s;
        System.out.println((new StringBuilder()).append("s1 : ").append(s).toString());
        System.out.println((new StringBuilder()).append("s2 : ").append(s1).append("\n").toString());
        s1 = (new StringBuilder()).append(s1).append("bar").toString();
        System.out.println((new StringBuilder()).append("s1 : ").append(s).toString());
        System.out.println((new StringBuilder()).append("s2 : ").append(s1).append("\n").toString());
        Integer integer = Integer.valueOf(1);
        Integer integer1 = integer;
        System.out.println((new StringBuilder()).append("i1 : ").append(integer).toString());
        System.out.println((new StringBuilder()).append("i2 : ").append(integer1).append("\n").toString());
        integer1 = Integer.valueOf(integer1.intValue() + 2);
        System.out.println((new StringBuilder()).append("i1 : ").append(integer).toString());
        System.out.println((new StringBuilder()).append("i2 : ").append(integer1).toString());
    }
}

Es ist etwas schwer zu erkennen, aber beide werden durch zusammengesetzte Zuweisung neu geschrieben, um ein neues Objekt zu erstellen und das Referenzziel zu ändern. Als ich das noch nicht wusste, sagte ich: "Ich möchte mehrere Ints und Doubles in einer Methode zurückgeben, aber es ist mühsam, eine Klasse nur dafür zu erstellen, und Ints und Doubles können nur als Wert übergeben werden. Ich dachte: "Ist es nicht möglich, es als Argument zu führen?"

Zusammenfassung

Um das oben Gesagte zusammenzufassen, schließen wir, dass ** unveränderliche Typen es Ihnen nicht erlauben, den Wert eines einmal erstellten Objekts zu ändern, sodass sich selbst das Übergeben als Referenz im Wesentlichen genauso verhält wie das Übergeben als Wert **. Werden. Entschuldigung.

Recommended Posts

Ein bisschen mehr über Referenzen ~ Verwenden von Python und Java als Beispiele ~
Ein bisschen mehr über FIFO
[Python] Kapitel 01-03 Über Python (Schreiben und Ausführen eines Programms mit PyCharm)
Über Python, aus und importieren, als
Ein Java-Programmierer studierte Python. (Über Typ)
Ein wenig mehr Details zur Einschlussnotation von Python
Eine Geschichte über Python Pop und Append
Python-Ausnahmebehandlung etwas bequemer
Ein Java-Programmierer studierte Python. (Über Funktionen (Methoden))
Ein Java-Programmierer studierte Python. (Über Dekorateure)
Ich habe eine Klasse in Python3 und Java geschrieben
Warum ich ein Java-Shop bin und Python starte
Erstellen Sie eine Webmap mit Python und GDAL
Eine Geschichte über das Ändern von Python und das Hinzufügen von Funktionen
Versuchen Sie, eine komprimierte Datei mit Python und zlib zu erstellen
Implementieren eines Generators mit Python> Link> Yield und next ()> Yield
(Für mich) Flask_2 (Liste und für, erweitert und ein bisschen mehr)
Was ich über KI / maschinelles Lernen mit Python gelernt habe (4)
Lösen mit Ruby, Perl, Java und Python AtCoder ATC 002 A.
Nehmen Sie Zeitraffer von einer PC-Kamera mit Python, OpenCV auf
Ich habe Chatbot mit LINE Messaging API und Python erstellt
Informationen zu Python-Objekten und -Klassen
Informationen zu Python-Variablen und -Objekten
Ich habe Java und Python verglichen!
Über Python, len () und randint ()
Informationen zu Python-Datums- und Zeitzone
Memorandum über Korrelation [Python]
Ein Memorandum über den Python-Mock
Über Python und reguläre Ausdrücke
Informationen zu Python- und Betriebssystemoperationen
Python # Über Referenz und Kopie
Über Python sort () und reverse ()
Ein Hinweis zu [Python] __debug__
Automatisierung einer Recherche zu geografischen Informationen wie dem Speichernetzwerk mithilfe von Python und Web-API
[Python] So kratzen Sie eine lokale HTML-Datei und geben sie mit Beautiful Soup als CSV aus
Erstellen Sie mit Python und Redis eine Rangliste für Spiele in der Alibaba-Cloud
Verarbeiten Sie das Ausführungsergebnis von Splunk mit Python und speichern Sie es in einer Datei
Erstellen Sie einen einfachen geplanten Stapel mit Dockers Python Image und parse-crontab
Nachdem ich die Python-Bibliothek recherchiert hatte, verstand ich ein wenig über ei.info.
[Python] Ich habe eine REST-API mit AWS API Gateway und Lambda geschrieben.
Ich habe Chatbot mit der LINE Messaging API und Python (2) ~ Server ~ erstellt
Aufbau einer LaTeX- und R-Umgebung (ein wenig Python) mit SublimeText3 (Windows)
Python a + = b und a = a + b sind unterschiedlich
Vorteile und Beispiele für die Verwendung von Rabbit Mq
Vergleich der grundlegenden Grammatik zwischen Java und Python
Ich habe einen Line-Bot mit Python gemacht!
Erstellen Sie mit tkinter eine Python-GUI
[Java] Ein wenig mysteriöses Split-Verhalten
Zeichnen einer Silbersteinkurve mit Python
Über Python-Diktat und sortierte Funktionen
Über Python und Cython dtype
Über Python Pickle (cPickle) und Marschall
[Python] Über Executor und zukünftige Klassen
Verwenden Sie Blender als Python-Modul
Clustering und Visualisierung mit Python und CytoScape
[Python] gibt A [oder / und] B zurück
Die Geschichte der Verwendung von Python reduziert
Starten Sie das Python-Skript im Dienst
Ein Hinweis zu Mock (Python-Mock-Bibliothek)