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

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

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

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

Q&A

2回答

13595閲覧

list型を継承したクラスについて

foo45

総合スコア106

Python

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

0グッド

0クリップ

投稿2015/10/23 12:01

python

1# -*- coding: utf-8 -*- 2 3class TestExtends(list): 4 5 def __init__(self): 6 list.__init__(self) 7 8 def append(self,value): 9 list.append(self,value) 10 print u"値が追加されました:" + str(value) 11 12 13if __name__ == "__main__": 14 15 test = TestExtends() 16 test.append("python") 17 test.append("-") 18 test.append("izm") 19 20 print "===============" 21 22 for i in test: 23 print i 24

上記のコードのコンストラクタ内でスーパークラスの初期化メソッドを呼び出す理由がわからないです。
例えば自分で独自につくったクラスならコンストラクタ内でなにか定義しているので初期化メソッドを呼び出してそれを使えるようにする、というのはわかりますが、list型の初期化メソッドを呼び出して何があるのですか?
そして、このlist.append(self, value)というのがよくわからないです。
listクラスのappend()メソッドを呼び出して何になるのでしょうか、、、そもそもlist型を継承しているのだからself.append()でもいいんじゃ...
と思うのですが、動かないのでダメなんですよね。いったい何が起こっているか教えて下さい。お願いします

参照させてもらったwebサイト様
http://www.python-izm.com/contents/application/class_extend.shtml

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

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

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

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

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

guest

回答2

0

list型の初期化メソッドを呼び出して何があるのですか?

特に何もないと思います。
ご質問のコードは、

python

1class TestExtends(list): 2 3 def append(self,value): 4 list.append(self,value) 5 print u"値が追加されました:" + str(value)

と書いても、基底クラスのコンストラクタを呼んで動作するはずです。
おそらく、学習のためクラス継承を分かりやすくするように書いているのでは。

投稿2015/10/24 01:41

Lhankor_Mhy

総合スコア36057

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

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

0

継承するということは継承元、ここではlistの機能を拡張するのが目的ですよね。

1つ目の初期化メソッドを呼び出さないとどうなるか?
test = TestExtends()を実行してもlistの初期化と同等の処理が呼ばれません。
ではどんな処理を行っているか?について、listは組込型なのでCのコードですが、list_init(PyListObject *self, PyObject *args, PyObject *kw)が具体的な処理です。
ここで何をやっているのか詳細に知らなくても問題ありませんが、この処理が呼ばれないので動かないのも当然です。

2つ目のappend()メソッドについて、機能を拡張するとはどういう事かというと「元の処理+追加処理」に他なりません。

  • 元の処理→list.append(self.value)
  • 追加処理→print u"値が追加されました:" + str(value)

self.append(value)にすると再帰呼び出しになり終了条件がないので無限ループになってしまいます。
実際に実行すると再帰呼び出しの回数上限に引っかかりエラーになります。


list.init()呼び出しの違いが分かるサンプルコード追記

# -*- coding: utf-8 -*- class TestExtends(list): def __init__(self): list.__init__(self) def append(self,value): list.append(self,value) print u"値が追加されました:" + str(value) if __name__ == "__main__": test = TestExtends() test.append("python") test.append("-") test.append("izm") test.__init() # list.__init__()を呼び出すとリストが初期化されます。 # passだと変化ありません。 print "===============" for i in test: print i
# -*- coding: utf-8 -*- class TestMoreExtends(list): def __init__(self, *args, **kw): list.__init__(self, *args, **kw) def append(self,value): list.append(self,value) print u"値が追加されました:" + str(value) if __name__ == "__main__": test = TestExtends([1, 2, 3]) # list.__init()を呼び出すとコンストラクタで初期値を設定できます。 # passだと初期値を設定できません。 test.append("python") test.append("-") test.append("izm") print "===============" for i in test: print i

投稿2015/10/23 13:56

編集2015/10/24 03:49
shiena

総合スコア1825

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

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

foo45

2015/10/23 14:10

もとの機能+上書きの機能がlist型やdict型を継承した機能拡張のクラスというわけですね。 ということはlist型を継承せずにlist型に酷似したクラスを一から作ることも可能というわけでしょうか?
shiena

2015/10/23 14:13

はい、難易度は別として、可能か不可能かで言えば可能です。
foo45

2015/10/23 15:45

すみません。質問させてください。 手元で動かしてみたのですが、listの__init__を呼び出さず、def __init__: passでも、スーパークラスの__init__関数自体が無しでも同じように動くのですが、これは何故ですか?
shiena

2015/10/23 16:52 編集

すみません、私も勘違いしていた部分があるので訂正しつつ説明します。 回答にリンクしたlistの初期化の関数を間違えていたので修正しました。 まず、listの__init__と同じ引数になるようにTestExtendsの__init__を次のように変更します。 def __init__(self, *args, **kw):  list.__init__(self, *args, **kw) # ↑はインデントが消えるので全角スペースを使っています。この行をコピペすると動きません 次にmainの方でtestを引数ありで次のように初期化します。 test = TestExtends([1, 2, 3]) すると実行結果は初期化の引数とappendしたものになります。 1 2 3 python - izm 次に__init__: passに変えて実行すると[1, 2, 3]が含まれていません。 もう1つ、3回append()した後にtest.__init__()を追加して実行してみてください。 list.__init__を呼び出した方はtestが空になり、passの方は変化しません。 初期化し直したはずなのに値が残っていますので、「元の処理+追加処理」ではなく「上書き」になっています。 このように初期化とappendだけでは同じように動いて見えるのですが、他の部分で動作が違っています。
foo45

2015/10/26 08:36

自分でもパターンを作りいろいろ試してみたので基本的な動きは分かりました。 これから書くプログラムに積極的に取り入れていきたいと思います。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問