A little more about references ~ Using Python and Java as examples ~

Introduction

The article "About python reference" was interesting, so I made a note. In this article,

When I started python, the first thing I stumbled upon was the mysterious explanation that is often seen everywhere: "All python arguments are passed by reference."

There was a passage. As already pointed out in the comments, to be more precise, "all Python arguments are passed by reference", but anyway, it seems that Python doesn't have passing by value! Previously, I wrote an article "Passing by value, passing by reference, and passing by reference" with almost the same theme, where integers and floating point numbers are used. I wrote that the number is passed by value in Python. In fact, it gave a consistent explanation, and in the original article

When a new object itself is assigned to a variable, it will refer to the place where the new object was created instead of the previous reference destination.

That part is the same as what I wrote in the explanation about passing references by value. However, I looked at the comments and I might have written something a little inaccurate, so I investigated it in detail.

Integer behavior in Python and C ++

Consider the following 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

This is certainly "passing by reference", not "passing by value". Because if you pass by value, the id (pointer value) should not match as in C ++ below.

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

What if this happens next?

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

In this way, unlike C ++, in Python, if you assign a different value, the id will also change. In other words, the reference destination changes. What about compound assignments like + =?

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

This is the same. As you can see in the comment of the original article, b + = 2 is actually called b = b + 2, and a new reference is also assigned. In other words, in Python, "every time you change the value of an integer, a new object is created in memory and it is assigned, so the id also changes". In other words, in Python, "once you generate an integer in memory, you can't change it", which is called "** immutable ". The opposite is " mutable **". Other immutable types include floating point numbers, booleans, strings, tuples, and None, and what is essential in Python is "mutable or not" rather than "passing by value". It will be. I didn't know.

Java strings and wrapper classes

By the way, Java has something similar to the Python example above. Wrapper classes such as String and Integer and 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

In this way, Java Strings and Integers behave like passing by value, even though they are reference types. Let's try decompiling the class file created by compiling the above using jad.

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());
    }
}

It's a little hard to see, but both are rewritten by compound assignment to create a new object and change the reference destination. When I didn't know this yet, I said, "I want to return multiple ints and doubles in a method, but it's a hassle to create a class just for that, and ints and doubles can only be passed by value. I thought, "Isn't it possible to pass it as an argument?"

Summary

To summarize the above, we conclude that ** immutable types do not allow you to change the value of an object once created, so even passing by reference will behave substantially the same as passing by value **. Become. Excuse me.

Recommended Posts

A little more about references ~ Using Python and Java as examples ~
A little more about FIFO
[Python] Chapter 01-03 About Python (Write and execute a program using PyCharm)
About Python, from and import, as
A Java programmer studied Python. (About type)
A little more detail on python comprehensions
A story about Python pop and append
Python exception handling a little more convenient
A Java programmer studied Python. (About functions (methods))
A Java programmer studied Python. (About the decorator)
I wrote a class in Python3 and Java
Why I'm a Java shop and start Python
Create a web map using Python and GDAL
Create a Mac app using py2app and Python3! !!
A story about modifying Python and adding functions
Try creating a compressed file using Python and zlib
Implementing a generator using Python> link> yield and next ()> yield
A little bit from Python using the Jenkins API
(For myself) Flask_2 (list and for, extends, and a little more)
What I learned about AI and machine learning using Python (4)
Solving with Ruby, Perl, Java and Python AtCoder ATC 002 A
Shoot time-lapse from a PC camera using Python and OpenCV
I made a Chatbot using LINE Messaging API and Python
About python objects and classes
About Python variables and objects
I compared Java and Python!
About Python, len () and randint ()
About Python datetime and timezone
A memorandum about correlation [Python]
A memorandum about Python mock
About Python and regular expressions
About Python and os operations
Python # About reference and copy
About Python sort () and reverse ()
A note about [python] __debug__
Automation of a research on geographical information such as store network using Python and Web API
[Python] How to scrape a local html file and output it as CSV using Beautiful Soup
Build a game leaderboard on Alibaba cloud using Python and Redis
Process Splunk execution results using Python and save to a file
Create a simple scheduled batch using Docker's Python Image and parse-crontab
After researching the Python library, I understood a little about egg.info.
[Python] I wrote a REST API using AWS API Gateway and Lambda.
I made a Chatbot using LINE Messaging API and Python (2) ~ Server ~
LaTeX and R (a little Python) environment construction with SublimeText3 (Windows)
Python a + = b and a = a + b are different
Benefits and examples of using RabbitMq
Java and Python basic grammar comparison
I made a Line-bot using Python!
Create a python GUI using tkinter
[Java] A little mysterious split behavior
Drawing a silverstone curve using python
About python dict and sorted functions
About dtypes in Python and Cython
About Python pickle (cPickle) and marshal
[Python] About Executor and Future classes
Use blender as a python module
Clustering and visualization using Python and CytoScape
[Python] return A [or / and] B
A story about using Python's reduce
Launch a Python script as a service
A note about mock (Python mock library)