質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

944閲覧

pythonのclass内listについて

ueda2525

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2022/11/04 09:16

編集2022/11/04 09:37

前提

pythonでlistを内包するclassオブジェクトを複数作成してもlistだけ共有されてしまいます。

実現したいこと

listも個別であって欲しいです。

発生している問題・エラーメッセージ

listを内包するclassを複数作成した所、listだけ共有されてしまいます。

該当のソースコード

python

1class test : 2 def __init__(self, d): 3 self.data.append(d) 4 self.data2 = d 5 data = [] 6 data2 = 0 7 8a = test(1) 9b = test(2) 10c = test(3) 11 12print(a.data2,b.data2,c.data2,len(a.data),len(b.data),len(c.data))

試したこと

該当のソースコードを実行すると
1 2 3 3 3 3
と表示されます。
期待する動作としては
1 2 3 1 1 1
であって欲しいです。
data2(リスト)だけ共有されてしまっている感じです。

補足情報(FW/ツールのバージョンなど)

a = test(1)
b = test(2)
c = test(3)
d = test(4)

print(a.data2,b.data2,c.data2,len(a.data),len(b.data),len(c.data))

とすると
1 2 3 4 4 4
となります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2022/11/04 09:21

エラーの出ない形でソースコードを提示いただけませんか。
TakaiY

2022/11/04 09:21

pythonはインデントがわからないと読めないので、コードを<code>ボタンで出てくる```と```の間に入れてください。 質問は編集できます。
ueda2525

2022/11/04 09:28

TakaiY様。失礼いたしました。編集させて頂きました。
PondVillege

2022/11/04 09:48

現状のコードだと,class testが作成された時点で,リストdataは全てのclass testで同一のものを扱ってしまうので,初期化__init__()ごとにリストを用意しなくてはなりません. https://paiza.io/projects/NEutP1v5SDpGsFE4rUHPfA
guest

回答2

0

ベストアンサー

__init__メソッドはクラスのインスタンスが生成された後に呼ばれます。インスタンスが持つべきクラス変数はここで生成する必要があります。

質問のコードの「data = []」はインスタンス変数でなくクラス変数なので、クラスのインスタンス共通のデータとなります。

ちなみに、「self.data.append()」としても、リストdataは生成されません。 この時上位階層を探してそれを利用しようとします(なのでクラス変数に入ってしまう)が、無ければエラーとなります。

元の形で修正するならこんな感じでしょうか。

python

1class test : 2 def __init__(self, d): 3 self.data = [] 4 self.data.append(d) 5 self.data2 = d

こちらの方がすっきりしますね。

python

1class test : 2 def __init__(self, d): 3 self.data = [d] 4 self.data2 = d

投稿2022/11/04 09:55

TakaiY

総合スコア12765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ueda2525

2022/11/04 10:06

的確なご回答ありがとうございます。Pythonは初心者で、C/C++などの感覚でコードを書いいましたが、Pythonではこのコードはインスタンスが共有されてしまうのですね。理解いたしました。
guest

0

python

1 data = [] 2 data2 = 0

ここに書いた変数はクラス変数で、インスタンス間で共有されます。

python

1 self.data.append(d)

これは、self.data でインスタンス変数dataを参照していますが、インスタンスに変数がないのでクラス変数のdataを取り出します。そして .append(0) でクラス変数のdataに要素を追加します。

python

1 self.data2 = d

これは、インスタンス変数 data2 を定義して、d を代入します。クラス変数のdata2は使用しません。

メモリ構成図:
イメージ説明

各変数辞書の内容確認

python

1>>> class test : 2... def __init__(self, d): 3 ... self.data.append(d) 4 se... self.data2 = d 5... data = [] 6... data2 = 0 7... 8>>> a = test(1) 9>>> b = test(2) 10>>> c = test(3) 11>>> globals() 12{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 13 'test': <class '__main__.test'>, 14 'a': <__main__.test object at 0x7f233f5d0b80>, 15 'b': <__main__.test object at 0x7f233f4fd4c0>, 16 'c': <__main__.test object at 0x7f233f506640>} 17>>> vars(test) 18mappingproxy({'__module__': '__main__', 19 '__init__': <function test.__init__ at 0x7f233f4c0310>, 20 'data': [1, 2, 3], 21 'data2': 0, '__dict__': <attribute '__dict__' of 'test' objects>, '__weakref__': <attribute '__weakref__' of 'test' objects>, '__doc__': None}) 22>>> vars(a) 23{'data2': 1} 24>>> vars(b) 25{'data2': 2} 26>>> vars(c) 27{'data2': 3}

投稿2022/11/04 09:47

編集2022/11/04 10:24
shiracamus

総合スコア5406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ueda2525

2022/11/04 10:06

的確なご回答ありがとうございます。Pythonは初心者で、C/C++などの感覚でコードを書いいましたが、Pythonではこのコードはインスタンスが共有されてしまうのですね。理解いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問