🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

1回答

881閲覧

python3 クラスを用いたトランプの問題

17issosu

総合スコア6

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2019/10/12 00:09

編集2019/10/12 00:24

前提

Python3 でオブジェクト指向の勉強をしています。トランプのカードを表示するクラスを作っているのですが、エラーメッセージが出てしまい解決出来ません。
このプログラムの出力結果は「♠A♣J♡Q♢K」となってほしいのですが、前半の♠A♣Jのみ出力出来て、後半に関しては下記のようなエラーが出てしまいます。

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

TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'

該当のソースコード

python3

1 2class PlayingCard: 3 """definition of Playing Card""" 4 5 6 def __init__(self,suit,number): 7 self.suit=suit 8 self.number=number 9 10 def output(self): 11 12 SU=self.suit 13 NU=self.number 14 15 if NU==1: 16 print(SU,"A") 17 elif NU==11: 18 print(SU,"J") 19 elif NU==12: 20 print(SU,"Q") 21 elif NU==13: 22 print(SU,"K") 23 else: 24 print(SU,NU) 25 26 27card1 = PlayingCard('♠',1) 28card2 = PlayingCard('♣',11) 29card3 = PlayingCard('♡',12) 30card4 = PlayingCard('♢',13) 31print(card1.output() , card2.output() , card3.output() , card4.output()) 32 33

試したこと

最後のprintで+ではなく,で代用すると

♠ A
♣ J
♡ Q
♢ K
None None None None

という出力を得ました。

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

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

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

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

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

meg_

2019/10/12 00:21 編集

ソースコードはインデントが判るように「コードの挿入」で記入してください。 エラーメッセージは全文掲載してください。
guest

回答1

0

outputメソッドの中でprintせずに、値をreturnして下さい。
この場合メソッド名も見直した方が良いでしょう。outputしないことになりますし。

発展

このような場合、特殊メソッド__str__を実装するのが賢い方法です。
それならばいちいちメソッドを呼ばずとも、f'{card1}{card2}{card3}{card4}' で済みます。

コードの書き方について

teratailには、コードを見やすく表示する機能があります。
質問編集画面を開き、コードを選択した状態で<code>ボタンを押して下さい。
Python

特にPythonの場合、インデントが崩れるとコードの意味が変わってしまいます。

投稿2019/10/12 00:19

編集2019/10/12 00:22
LouiS0616

総合スコア35668

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

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

meg_

2019/10/12 00:25

ご回答の通りかと思いますが、「前半の♠A♣Jのみ出力出来て」なのは何故でしょうね?
LouiS0616

2019/10/12 00:31 編集

ひょっとしたら、こんな認識なのかもしれません。 --前半-- ♠ A ♣ J ♡ Q ♢ K --後半-- TypeError
Zuishin

2019/10/12 00:34

card1.output() + card2.output() + card3.output() + card4.output() この前半二つは評価された時点で内部で print が呼ばれますが、その結果両方の戻り値 None を + しようとしてエラーが出ているんだと思います。
meg_

2019/10/12 00:36

なるほど。。。あり得ますね。コメントありがとうございます。
Zuishin

2019/10/12 00:36

プラスをカンマに変えた時に None が四つ出てくるのも同じ理屈でしょう。
meg_

2019/10/12 00:40

コードを試してみました。Zuishin様の言う通りでした。勉強になります。
LouiS0616

2019/10/12 00:43 編集

> この前半二つは評価された時点で... なるほど、確かに実行したらそのような結果になりました。 てっきり全てのオペランドを先に評価しているのかと思っていました。 まあ a + b + c + d が ((a + b) + c) + d であることを考えるとそれが自然ですね。 > プラスをカンマに変えた時に None が四つ出てくるのも同じ理屈でしょう。 これについては、ちょっと関連性が分かりません。もう少し詳しくお聞かせ頂いても良いでしょうか?
Zuishin

2019/10/12 00:43

要するに、四つの式が全て評価された後、次のようになっているということです。 print(None, None, None, None)
Zuishin

2019/10/12 00:44 編集

output() が値を戻しているのではなく、print しているのが諸悪の根源です。いや、その結果を最後に print している方が悪いのかもしれません。
LouiS0616

2019/10/12 00:45

関数の実引数の評価順序と、オペランドの評価順序はあまり同一視しないように思います。
Zuishin

2019/10/12 00:47

card1.output() card2.output() card3.output() card4.output() 上のようにしたら質問者さんの思惑通りの結果になると思います。 output() の中にすでに print が含まれているので。 しかし、print(card1.output() , card2.output() , card3.output() , card4.output()) とすると、四つの戻り値 None を更に出力してしまいます。
LouiS0616

2019/10/12 00:47

> print しているのが諸悪の根源 あ、その観点で『同じ理屈』という意味でしょうか?
LouiS0616

2019/10/12 01:07 編集

そうですね。 メソッド内でprintしていることが問題だと言うことは認識しており、回答にも記載しているつもりです。 コメントありがとうございます。
Zuishin

2019/10/12 00:55

プラス演算子がカンマ演算子に変わっただけなので、同じ理屈と表現しました。プラス演算子は None と None の演算でエラーになりますが、カンマ演算子はそうなりませんから。
LouiS0616

2019/10/12 01:06 編集

カンマは演算子ではなく構文の一部ですよ。 Cにはカンマ演算子が存在しますが、これも関数の引数を区切るカンマとは別物です。
Zuishin

2019/10/12 00:59

何と呼ばれる構文でしょうか?
LouiS0616

2019/10/12 01:00

強いて言うなら『関数呼び出し』の構文の一部です。 文脈によってはタプルリテラルになります。
Zuishin

2019/10/12 01:02

ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問