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

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

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

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

Q&A

解決済

4回答

7111閲覧

python3 プロパティの必要性が分かりません。

shero4869

総合スコア8

Python 3.x

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

1グッド

2クリップ

投稿2020/03/12 08:12

前提・実現したいこと

プロパティの必要性については、
例えばnameというインスタンス変数クラスの中で使っていて、それをあとからcute_nameに変えた時、コード全体のnameを片っ端からcute_nameに書き換えないといけない。それが膨大な数だととても大変。しかし、プロパティを使っていれば、クラスの中のインスタンス変数を書き換えるだけでOKなので楽。
という風に理解しています。しかし、プロパティを用いて書いた下のコード1と用いずに書いたコード2、どちらもクラスの中のインスタンス変数を変更するだけで大丈夫だと思います。
なぜプロパティを使う必要があるのでしょうか?もっと高度なコードになると楽になる場面があるのでしょうか?

コード1

python

1class Dog(): 2 def __init__(self): 3 self.__name="one" 4 5 @property 6 def name(self): 7 pass 8 9 @name.getter 10 def name(self): 11 return self.__name 12 13 @name.setter 14 def name(self,name): 15 self.__name=name 16 17 18dog=Dog() 19dog.name="taro" 20print(dog.name)

###コード2

python

1class Dog(): 2 def __init__(self): 3 self.name="one" 4 5 6 7 def set_name(self,name): 8 self.name=name 9 10 def get_name(self): 11 return self.name 12 13 14dog=Dog() 15dog.set_name("taro") 16print(dog.get_name())
s.k👍を押しています

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

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

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

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

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

guest

回答4

0

これは全然本質的な回答じゃないのですが、

https://teratail.com/questions/27789
最近のプログラミング言語にgetter/setterがないのはなぜ?

回答についている、2016/02/21 11:18 の yuba さんのコメント

yohhoyさんのお答えの通りかと思いますが、歴史的経緯としては「Javaのgetter/setter方式がよろしくないからプロパティ方式が広まった」というよりは、「プロパティ方式を取り込もうとしたJava陣営が、文法ルール拡張を避けるためにgetter/setterのメソッド名ルールという規約でプロパティを表現することにした」の方がより実体に近いと思います。

が私の認識と一致します。

リスト1の発想、つまりx.a = b というコードが x.set_a(b) のようなプロシジャや関数の呼び出しに(内部的に)置き換えられるという機構の方が歴史的には先で、
リスト2の発想つまり、x.set_a(b)だけあればいいだろ、という慣習の方が後のように思っています。


それはそれとして、上で挙げた質問や、回答からリンクされているWhy getter and setter methods are evil が参考になるかと思いましたので。

投稿2020/03/12 10:13

quickquip

総合スコア11038

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

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

0

ベストアンサー

プロパティは「属性参照によって任意の処理を走らせることができる」のが必要性です。単なるゲッター/セッターの代替ではありません。プロパティの役割は「メソッド呼び出しを属性参照に偽装すること」です。
(ついでにぞっとするかもしれないことを書いておくと、多くのPythonのライブラリでは「他の言語の文化ではゲッター/セッターを用いるかもしれないもの」を、プロパティですらない単なる属性として実装しています。「隠蔽? そんなの『まともに使えば』必要ないよ」という文化です。まあそれでも、必要と認められたときはゲッター/セッターの代替としてのプロパティも書かれるのですが)

たとえば、xy座標のあるグラフ上の図形みたいなオブジェクトを定義したとします。

python

1# ...はこのサンプルコードでは省略を表す 2class HogeFigure: 3 def __init__(self, x, y, ...): # x, yは中心座標とかそんなイメージ 4 self.x = x 5 self.y = y 6 ... 7

このオブジェクトから原点からの距離を取りたいとします。これは本質的に属性として持つ必要はありませんが、メソッド呼び出しにするべきでしょうか? 性質は属性です。

それでもまあ、移動しない図形なら__init__self.distance_from_origin = (self.x**2 + self.y**2)**0.5とか書いておけばいいのかもしれません。図形の移動をサポートしようとすると厄介です。

動かすたびに計算し直すのは、頻繁に動かすなら無駄でしょう。しょっちゅう動かすけど、原点からの距離そのものは必要になる機会はそれほど多くないというシチュエーションなら、メソッド呼び出しにして必要なときだけ計算させたいところです。distance_from_originメソッドを用意すればいいのですね。

でも、性質としては属性なんじゃなかったっけ? なんで引数取る訳でもないのにメソッドとして呼ばないといけないのかわかりません。xyと同様に扱えてほしいのです。

おまたせしました、プロパティの出番です。

python

1class HogeFigure: 2 def __init__(self, x, y, ...): 3 self.x = x 4 self.y = y 5 ... 6 7 @property 8 def distance_from_origin(self): 9 return (self.x**2 + self.y**2)**0.5

これはゲッターとして機能しますが、セッターもいけます。他の言語でのシチュエーションと同じです。図形を頻繁に動かすことは想定せず、distance_from_originを「普通の属性」として持つ設計にしたとしましょう。そしてx, y属性への代入は想定するとします。

xyが書き換えられたらdistance_from_originも変えないといけません。まあ、上でやったみたいにこっちをプロパティにした方が良い気はしますが、お望みならxyをプロパティにしてその中で再計算させることができる訳です。

あるいはまた異なったシチュエーションで、distance_from_originをプロパティにすると、こっちへ代入されたら整合が取れるようにxyを変える、みたいな動作も考えられます。ちょっと実際のシチュエーションと挙動の想像が難しいですが(まあ同じ向きのベクトルとしてノルムだけ変えれば良いのかな)、動作としては成立します。

このように「属性アクセスでメソッドが呼び出せるので、色々なことができる」というか「メソッドを属性に見せられる」きがプロパティの存在意義で、上手く使うと単なるアクセス制御以外のことができます(必要なときに計算させるとか、データ整合性の確保をやったり、リソースの取得や解放に使うとか)。

参考
公式リファレンスの中にあるもの(めぼしいのはこれくらい?)

いにしえの昔にpropertyが追加されたときの説明
属性アクセス | What's New in Python 2.2 — Python 3.8.2 ドキュメント

もう少し詳しいやつ
デスクリプタ HowTo ガイド — Python 3.8.2 ドキュメント

同じような議論をしているページ

(以前ググったときは他にもいくつかあった気がするので、見つけたら追加)
propertyについて - podhmoの日記

投稿2020/03/12 09:06

hayataka2049

総合スコア30933

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

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

0

かなりの数の洗練された Python クラスが、 getattr() を使って属性アクセスのフックを定義しています; もっとも一般的なのは、 obj.parent のような属性アクセスを obj.get_parent のようなメソッド呼び出しに自動的にマッピングすることによって、コードを読みやすくするための便宜としてです。Python 2.2 は属性アクセスをコントロールする新しい方法を追加しました。

What's New in Python 2.2 — Python 3.8.2 ドキュメント
https://docs.python.org/ja/3/whatsnew/2.2.html?highlight=property#attribute-access

もっと噛み砕いて説明すると、プロパティはアクセサメソッド(コード2の書き方)を書きやすく読みやすくしたものです。

dog.set_name("taro")よりもdog.name="taro"の方がオブジェクト指向として直観的でしょ?ということですね。

なぜプロパティを使う必要があるのでしょうか?もっと高度なコードになると楽になる場面があるのでしょうか?

考え方が逆です。
Python では、「クラスの属性」を表現する方法としてプロパティがスタンダードなのですから、アクセサメソッドを使う必要がないのです。

投稿2020/03/13 06:39

nskydiving

総合スコア6500

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

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

0

なぜプロパティを使う必要があるのでしょうか?

set_nameget_nameがプロパティの代替になると思っているのであれば不要です(実際、JavaではgetName/setNameのようなメソッドを使います)。

決まりきった接頭辞やカッコを書くのが煩わしい、というのであれば、プロパティが便利です。

投稿2020/03/12 08:25

maisumakun

総合スコア145184

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問