New instance overwrites old values

Asked

Viewed 48 times

6

Take a look at this class:

class Signal:
    point = None
    view = {
        "x": None,
        "y": None,
        }
    def __init__(self, point):

        self.point = point

        self.set_position()

        print(self.point + " -> " + str(self.view["x"]) + "x" + str(self.view["y"]))

    def set_position(self):
        if self.point == "north":
            self.view["x"] = 150
            self.view["y"] = 200
        else:
            self.view["x"] = 300
            self.view["y"] = 400

    def check(self):
        print(self.point + " -> " + str(self.view["x"]) + "x" + str(self.view["y"]))

And now in the following result to instantiate 2 different variables like this object and check the values:

>>> s1 = Signal("north")
north -> 150x200
>>> s2 = Signal("south")
south -> 300x400
>>> s1.check()
north -> 300x400

I just can’t find the logic of it. Can you explain why when creating the s2 the values of s1 are exchanged?

2 answers

5


This here...

class Signal:
    point = None
    view = {
        "x": None,
        "y": None,
        }

    ...

# fim da classe

...You don’t do what you think you do. Declaring variables at the top of the class in this way causes them to be shared among all class specimens (similar to static other languages). To declare fields in your class, the proper way in Python is:

class Signal:

    def __init__(self, point):
        self.point = None
        self.view = {
            "x": None,
            "y": None,
            }

    # demais métodos

# fim da classe

That is, incialize them in the constructor, placing the same right at the beginning of the class, to facilitate reading.

  • 1

    Python has many banana peels for that is coming out of other languages. Thank you so much for the help.

2

Can you explain why I created the s2 the values of s1 are exchanged?

Because the variables point and view are class attributes Signal and not of the instance.

Class attributes are attributes whose owner is the class itself, which will be shared with all instances of the class. To define unique attributes to an instance, set the variables in the __init__:

class Signal:
    def __init__(self, point):
        self.point = point
        self.view = { "x": None,
                      "y": None,
                    }

        self.set_position()

        print(self.point + " -> " + str(self.view["x"]) + "x" + str(self.view["y"]))

See DEMO

More details on documentation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.