Why is a stored function in an object property being overwritten (Python)?

Borealis

The following is a minimum working example of my problem where I have a school object containing an array of fish objects, and I want each fish to have properties based on their index. All I'm doing is setting the properties and then printing them out, both during the init and later once the class is fully instantiated. The problem is that setting these properties doesn't seem to work for functions. Also, it performs differently based on whether or not enumerate is used (which I would like to understand).

In the following code the output reveals that the 'func' property of the fish in my school object is being overwritten, but the 'x' property isn't.

class Fish:
    def __init__(self):
        self.x = -1
        self.func = lambda y: -1


class School:
    def __init__(self):
        self.fishList = [Fish() for i in range(2)]
        for fishIndex, f in enumerate(self.fishList):
            f.x = fishIndex
            f.func = lambda y: fishIndex
        print("No enumerate:")
        for f in self.fishList:
            print(f.x, f.func(0))
        print("Enumerate")
        for fishIndex, f in enumerate(self.fishList):
            print(f.x, f.func(0))

mySchool = School()
print("-----------------------------------------")
print("No enumerate:")
for f in mySchool.fishList:
    print(f.x, f.func(0))
print("Enumerate:")
for fishIndex, f in enumerate(mySchool.fishList):
    print(f.x, f.func(0))


Output:

No enumerate:
0 1
1 1
Enumerate
0 0
1 1
-----------------------------------------
No enumerate:
0 1
1 1
Enumerate:
0 1
1 1

So far I have tracked the issue to originating from the how I store the fish. If I store the fish separately, as opposed to in the array, the functions persist correctly. So this makes me think that this is a mutability/pointers issue. But were that the case I would expect 'x' to not persist correctly either.

Edit: To clarify, in the output the first "Enumerate" before the dashed lines is what I expected for all of the outputs.

chepner

In the definition of func, fishIndex is a free variable. That means the name itself, not the current value of fishIndex, is part of the function definition.

When the function is called, it will use the current value of the local variable fishIndex defined in __init__.

While inside __init__, that variable changes when you use it as an index variable in the for loop.

Outside __init__, fishIndex still refers to the variable defined in __init__, even though that function returns. We say that func is a closure over the variables of the scope in which it was defined.

The fact that you are reusing the name fishIndex in your loop at the global scope does not affect the behavior of func.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Why is the previous object array entry being overwritten?

From Dev

Why isn't my local variable being overwritten in this function?

From Dev

What happens with python threads stored as class parameters that get overwritten? And why?

From Dev

Why is my array being overwritten?

From Dev

Call a Javascript function stored in an object property

From Dev

calling function stored as a property in an object in a for loop

From Dev

New object is being overwritten by previous object

From Dev

Object data being overwritten after creation

From Dev

FileWriter object reference not being overwritten as expected

From Dev

MS Access collection object value is being overwritten

From Dev

How to prevent object properties from being overwritten

From Dev

C++ Why is file not being appended or overwritten?

From Java

Why is my array being overwritten java

From Dev

why are my shared preference values being overwritten?

From Dev

Why is my state iterations being overwritten?

From Dev

Why is my firebase document being overwritten?

From Dev

Why are my HashMap Entries being overwritten?

From Dev

Input object of function will be overwritten by return

From Java

How to call a property of the base class if this property is being overwritten in the derived class?

From Dev

Why is my python list element (subarray) overwritten while being swapped with another?

From Dev

Python List and Dictionary being overwritten or corrupted?

From Dev

Python3 dictionary values being overwritten

From Dev

Why is @Input property standardLinks been overwritten?

From Dev

Why was my list not overwritten in python?

From Dev

Why is only one object being called [Python]

From Dev

Why this viewController property doesn't prevent the object from being deallocated?

From Dev

Why is VueJS detecting this property being added to an object in an array?

From Dev

Typescript inherited property initialized in a function is overwritten

From Dev

Python - Call a function of an object which is stored in a dict

Related Related

  1. 1

    Why is the previous object array entry being overwritten?

  2. 2

    Why isn't my local variable being overwritten in this function?

  3. 3

    What happens with python threads stored as class parameters that get overwritten? And why?

  4. 4

    Why is my array being overwritten?

  5. 5

    Call a Javascript function stored in an object property

  6. 6

    calling function stored as a property in an object in a for loop

  7. 7

    New object is being overwritten by previous object

  8. 8

    Object data being overwritten after creation

  9. 9

    FileWriter object reference not being overwritten as expected

  10. 10

    MS Access collection object value is being overwritten

  11. 11

    How to prevent object properties from being overwritten

  12. 12

    C++ Why is file not being appended or overwritten?

  13. 13

    Why is my array being overwritten java

  14. 14

    why are my shared preference values being overwritten?

  15. 15

    Why is my state iterations being overwritten?

  16. 16

    Why is my firebase document being overwritten?

  17. 17

    Why are my HashMap Entries being overwritten?

  18. 18

    Input object of function will be overwritten by return

  19. 19

    How to call a property of the base class if this property is being overwritten in the derived class?

  20. 20

    Why is my python list element (subarray) overwritten while being swapped with another?

  21. 21

    Python List and Dictionary being overwritten or corrupted?

  22. 22

    Python3 dictionary values being overwritten

  23. 23

    Why is @Input property standardLinks been overwritten?

  24. 24

    Why was my list not overwritten in python?

  25. 25

    Why is only one object being called [Python]

  26. 26

    Why this viewController property doesn't prevent the object from being deallocated?

  27. 27

    Why is VueJS detecting this property being added to an object in an array?

  28. 28

    Typescript inherited property initialized in a function is overwritten

  29. 29

    Python - Call a function of an object which is stored in a dict

HotTag

Archive