0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

class内のlistの初期化

Last updated at Posted at 2022-10-21
() 有無の違い
class cls:
    def __init__(self):
        self.lst = []

o  = cls
oo = cls()

print(o)    # <class '__main__.cls'>
print(oo)   # <__main__.cls object at 0x100ecf130>

print(type(o))   # <class 'type'>
print(type(oo))  # <class '__main__.cls'>

#print(o.lst)   # AttributeError: type object 'cls' has no attribute 'lst'
print(oo.lst)   # []
2回呼ぶ
class cls:
    def __init__(self):
        self.lst = []

o = cls
print(id(o))  # 5098446000
o = cls
print(id(o))  # 5098446000 2回目も同じモノを指している

o = cls()
print(id(o))  # 4311216432
o = cls()
print(id(o))  # 4311213696 1回目とは別のモノを指している
こう言うことがしたいので複数回呼ぶ
class cls:
    def __init__(self):
        self.lst = []
for i in ['banana','apple','orange','kiwi','grape']:
    o = cls()
    print(f'{id(o)} {o}')
    # o に関していろいろやりたいことをする
毎回、新しい o が作れている?
$ ./test.py 
4344637056 <__main__.cls object at 0x102f5e680>
4345200160 <__main__.cls object at 0x102fe7e20>
4344637056 <__main__.cls object at 0x102f5e680>
4345200160 <__main__.cls object at 0x102fe7e20>
4344637056 <__main__.cls object at 0x102f5e680>
$ 

2個のモノが順番で出てくる。。。ひとまず置いといて先へ。


うまくいく例(1)
class cls:
    def __init__(self):
        self.lst = []

for i in ['banana','apple','orange','kiwi','grape']:
    o = cls()
    o.lst.append(i)  # インスタンスを作るときに指定の値で作ってしまいたい
    print(o.lst)
$ ./test.py 
['banana']
['apple']
['orange']
['kiwi']
['grape']
$ 
うまくいく例(2)
class cls:
    def __init__(self,arg):
        self.lst = arg

for i in ['banana','apple','orange','kiwi','grape']:
    o = cls([i])
    print(o.lst)
$ ./test.py 
['banana']
['apple']
['orange']
['kiwi']
['grape']
$ 

実際には cls のメンバはたーーくさんあって、インスタンス作成時には値が決まらないものもあるので、値が決まってないメンバについてはデフォルト値をセットしてインスタンス作ってしまいたい。
後から append できるようにしたいので、デフォルト値として [] をセットしておきたい。


いろいろやった後に lst2 にセットする値が決まる例
class cls:
    def __init__(self,arg1 = [], arg2 = []):
        self.lst1 = arg1
        self.lst2 = arg2

for i in ['banana','apple','orange','kiwi','grape']:
    o = cls(arg1=[i])
    i = [i,0]
    if i[0] == 'kiwi':
        i = ['kiwi',10]
    o.lst2 += i
    print(f'{o.lst1} {o.lst2}')
望ましくない結果
$ ./test.py 
['banana'] ['banana', 0]
['apple'] ['banana', 0, 'apple', 0]
['orange'] ['banana', 0, 'apple', 0, 'orange', 0]
['kiwi'] ['banana', 0, 'apple', 0, 'orange', 0, 'kiwi', 10]
['grape'] ['banana', 0, 'apple', 0, 'orange', 0, 'kiwi', 10, 'grape', 0]
$ 

釈然としないし癪に触るけど、「インスタンス作成+値セット」を1行で書くのは諦める。


妥協結果
class cls:
    def __init__(self):
        self.lst1 = []
        self.lst2 = []

for i in ['banana','apple','orange','kiwi','grape']:
    o = cls()
    o.lst1.append(i)
    i = [i,0]
    if i[0] == 'kiwi':
        i = ['kiwi',10]
    o.lst2 += i
    print(f'{o.lst1} {o.lst2}')
$ ./test.py 
['banana'] ['banana', 0]
['apple'] ['apple', 0]
['orange'] ['orange', 0]
['kiwi'] ['kiwi', 10]
['grape'] ['grape', 0]
$

しかし、冒頭のテストでオブジェクトのIDは2個が繰り返し使われていた件は。。。
class cls:
    def __init__(self):
        self.lst1 = []
        self.lst2 = []

stack = []
for i in ['banana','apple','orange','kiwi','grape']:
    o = cls()
    print(f'{o} {id(o)}')
    o.lst1.append(i)
    i = [i,0]
    if i[0] == 'kiwi':
        i = ['kiwi',10]
    o.lst2 += i
    stack.append(o)

for i in stack:
    print(f'{id(i)} {i.lst1} {i.lst2}') 
$ ./test.py 
<__main__.cls object at 0x102ee2dd0> 4344131024
<__main__.cls object at 0x102ee2680> 4344129152
<__main__.cls object at 0x102f6be20> 4344692256
<__main__.cls object at 0x102f9a1a0> 4344881568
<__main__.cls object at 0x102f9a140> 4344881472
4344131024 ['banana'] ['banana', 0]
4344129152 ['apple'] ['apple', 0]
4344692256 ['orange'] ['orange', 0]
4344881568 ['kiwi'] ['kiwi', 10]
4344881472 ['grape'] ['grape', 0]
$ 

再現せず。。。。。なぜでしょうか????
以下のコードだと再現して2個のIDが使い回される。。。

使い回されるの再確認
class cls:
    def __init__(self):
        self.lst = []
for i in ['banana','apple','orange','kiwi','grape']:
    o = cls()
    print(f'{id(o)} {o}')
    o.lst = [i]
$ ./test.py 
4381402752 <__main__.cls object at 0x10526e680>
4381965856 <__main__.cls object at 0x1052f7e20>
4381402752 <__main__.cls object at 0x10526e680>
4381965856 <__main__.cls object at 0x1052f7e20>
4381402752 <__main__.cls object at 0x10526e680>
$ 
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?