LoginSignup
0
0

More than 3 years have passed since last update.

Pythonのクラスの変数に潜む地雷

Last updated at Posted at 2020-11-20

https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables

Class variables Python are strange.
If they are mutable, they act like STATIC PROPERTY in PHP;
If they are immutable, when they reassigned, the act like DYNAMIC PROPERTY in PHP.
It seems to do with reference.

class X:
    array: list = []
    immutable_array: tuple = ()
    static_v: str = 'ori'

    def __init__(self, name: str):
        self.name = name

    def init_ext(self):
        self.array = []  
        # or even use [self.name], just let it be another id

    def work(self):
        self.array.append(self.name)
        self.immutable_array = (len(self.array),)
        self.static_v = f"[{self.name}]"


if __name__ == '__main__':
    x1 = X("A")
    x2 = X("B")

    for i in range(3):
        print("x1 array: ", x1.array, 'tuple: ', x1.immutable_array, "v: ", x1.static_v),
        print("x1[id] array: ", id(x1.array), 'tuple: ', id(x1.immutable_array), "v: ", id(x1.static_v))
        print("x2 array: ", x2.array, 'tuple: ', x2.immutable_array, "v: ", x2.static_v)
        print("x2[id] array: ", id(x2.array), 'tuple: ', id(x2.immutable_array), "v: ", id(x2.static_v))
        x1.work()
        x2.work()

    print("finally")
    print("x1 array: ", x1.array, 'tuple: ', x1.immutable_array, "v: ", x1.static_v),
    print("x1[id] array: ", id(x1.array), 'tuple: ', id(x1.immutable_array), "v: ", id(x1.static_v))
    print("x2 array: ", x2.array, 'tuple: ', x2.immutable_array, "v: ", x2.static_v)
    print("x2[id] array: ", id(x2.array), 'tuple: ', id(x2.immutable_array), "v: ", id(x2.static_v))

Output:

x1 array:  [] tuple:  () v:  ori
x1[id] array:  4477451776 tuple:  4475306048 v:  4477483952
x2 array:  [] tuple:  () v:  ori
x2[id] array:  4477451776 tuple:  4475306048 v:  4477483952
x1 array:  ['A', 'B'] tuple:  (1,) v:  [A]
x1[id] array:  4477451776 tuple:  4476906464 v:  4477621936
x2 array:  ['A', 'B'] tuple:  (2,) v:  [B]
x2[id] array:  4477451776 tuple:  4476375872 v:  4477622000
x1 array:  ['A', 'B', 'A', 'B'] tuple:  (3,) v:  [A]
x1[id] array:  4477451776 tuple:  4476751488 v:  4477622064
x2 array:  ['A', 'B', 'A', 'B'] tuple:  (4,) v:  [B]
x2[id] array:  4477451776 tuple:  4476906464 v:  4477621936
finally
x1 array:  ['A', 'B', 'A', 'B', 'A', 'B'] tuple:  (5,) v:  [A]
x1[id] array:  4477451776 tuple:  4476375872 v:  4477622128
x2 array:  ['A', 'B', 'A', 'B', 'A', 'B'] tuple:  (6,) v:  [B]
x2[id] array:  4477451776 tuple:  4476751488 v:  4477622064

If you execute init_ext after initialization, the result changed.


x1 = X("A")
x2 = X("B")

x1.init_ext()
x2.init_ext()

# the same test codes as above

The output would be :

x1 array:  [] tuple:  () v:  ori
x1[id] array:  4327900992 tuple:  4325756992 v:  4327930800
x2 array:  [] tuple:  () v:  ori
x2[id] array:  4327899904 tuple:  4325756992 v:  4327930800
x1 array:  ['A'] tuple:  (1,) v:  [A]
x1[id] array:  4327900992 tuple:  4327849648 v:  4328077168
x2 array:  ['B'] tuple:  (1,) v:  [B]
x2[id] array:  4327899904 tuple:  4327372112 v:  4328077232
x1 array:  ['A', 'A'] tuple:  (2,) v:  [A]
x1[id] array:  4327900992 tuple:  4326822720 v:  4328077296
x2 array:  ['B', 'B'] tuple:  (2,) v:  [B]
x2[id] array:  4327899904 tuple:  4327849648 v:  4328077168
finally
x1 array:  ['A', 'A', 'A'] tuple:  (3,) v:  [A]
x1[id] array:  4327900992 tuple:  4327372112 v:  4328077232
x2 array:  ['B', 'B', 'B'] tuple:  (3,) v:  [B]
x2[id] array:  4327899904 tuple:  4326822720 v:  4328077296
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0