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

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

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

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

Q&A

解決済

3回答

510閲覧

pythonのmatch構文について

b.wist

総合スコア1

Python 3.x

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

0グッド

0クリップ

投稿2023/02/16 22:42

実現したいこと

下記のコードでmatch構文上だとdataclassを未適用時でもPoint(x=0,y=0)の記述方法が可能で、match構文外で同じように宣言するとエラーが発生します。これは何故でしょうか?

python

1class Point: 2 x: int 3 y: int 4 5def where_is(point): 6 match point: 7 case Point(x=0, y=0): 8 print("Origin") 9 case Point(x=0, y=y): 10 print(f"Y={y}") 11 case Point(x=x, y=0): 12 print(f"X={x}") 13 case Point(): 14 print("Somewhere else") 15 case _: 16 print("Not a point") 17if __name__ == "__main__": 18 point = Point(x=0, y=0) # 失敗する、がdataclassをPointに適用したら成功する 19 point.x, point.y = (0,0) # 成功する 20 where_is(point)

python

1Traceback (most recent call last): 2 File "/hogehoge/hoge.py", 3 point = Point(x=0, y=0) 4 ^^^^^^^^^^^^^^^ 5TypeError: Point() takes no arguments

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

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

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

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

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

guest

回答3

0

他の方の回答と同じですが、違う観点から。

Pointクラスの定義が、用途に対して不完全なのが原因です。
質問の定義では、クラス変数としてx、yを持ちます。ただし、__init__メソッドを新規定義しておらず、また、変更するためのメソッドも無いので、それぞれの値が0固定で変更できません。

この状態で

python

1point = Point(x=0, y=0)

このように、コンストラクタを呼ぶと、Pointクラスでは定義されていないので、デフォルトの何も引数を受け付けず、何もしない__init__メソッドが呼ばれます。 引数は受け付けないので、質問のエラーが発生します。
dataclassにするとできるのは、dataclassがクラス定義にしたがって、適切なコンストラクタを自動で生成するからです。
https://docs.python.org/ja/3/library/dataclasses.html#module-dataclasses

このモジュールは、__init__()__repr__() のような special method を生成し、ユーザー定義のクラスに自動的に追加するデコレータや関数を提供します。

caseの中のPoint()については、他の方の説明のとおりです。

投稿2023/02/17 01:27

編集2023/02/17 05:49
TakaiY

総合スコア12657

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

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

0

ベストアンサー

https://docs.python.org/ja/3/reference/compound_stmts.html#class-patterns

In simple terms CLS(P1, attr=P2) matches only if the following happens:

  • isinstance(<subject>, CLS)
  • convert P1 to a keyword pattern using CLS.match_args
  • For each keyword argument attr=P2:
    • hasattr(<subject>, "attr")
    • P2 matches <subject>.attr
  • ... and so on for the corresponding keyword argument/pattern pair.

case節ではこのように実行されるのであって、Point(x=0, y=0)が実行されるわけではないです。

投稿2023/02/16 23:58

quickquip

総合スコア11029

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

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

0

caseの後に続くPoint(x=0, y=0)match文のクラスパターンで
point = Point(x=0, y=0) の方はコンストラクタです。
なのでたまたま同じ形ですが意味が違っています。

caseの後に書く分にはdataclassである必要はありません。
(※case Point(0,0)と書くには必要)

投稿2023/02/16 23:51

ozwk

総合スコア13512

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問