简体   繁体   中英

Where does the ['boo there'] come from in this code example?

I have this function here and I am struggling to figure out how the output is derived from this. Any help would be appreciated. thank you!

class A:
    def __init__(self, a: int, b: [str]):
        self._foo = a
        self._bar = b

    def get_foo(self):
        return self._foo

    def get_bar(self):
        return self._bar



    def do_that(given: A):
        x = given.get_foo()
        x += 10
        y = given.get_bar()

        y[0] += ' there'

        y = ['cool']

        given = A(-10, ['bye'])


x = A(1, ['boo'])
print(x.get_foo())
print(x.get_bar())
do_that(x)
print(x.get_foo())
print(x.get_bar())

Can someone explain why this is the output? Where does ['boo there'] come from and the 1 right before that?

1
['boo']
1
['boo there']

The issue you are seeing is that in your do_that function, you are getting x and y from self._foo and self._bar . You modify both local variables. But when you print them out again, only self._bar changed.

The reason for this is that in python, the list type is mutable (can be changed), where the int type is immutable (and can only be replaced).

This means that when you get the y to self._bar and add "there" to element [0] , it is actually changing the list value held by the self._bar attribute.

But since self._foo is just an immutable value type, then assigning it to variable x and changing x will only result in x changing, not the original self._foo .

Proper programming would have you say self._foo += 10 if you want to change the instance attribute.

When you call y = given.get_bar() in the do_that() method it get_bar() actually return the reference of the _bar list reference. As list is mutable so it passed by reference.

And when you do the operation y[0] += ' there' it actually change the _bar list as y is the reference of _bar and its mutable and becomes ['boo there'] . But when you do y = ['cool'] it actually create a new list reference hence _bar previous reference lost. So it will not change the _bar anymore.

As a result after returning from the do_that() method when you call x.get_bar() it gives the result ['boo there']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM