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

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

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

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

Q&A

解決済

6回答

1707閲覧

クラスのメンバー変数をpublicじゃなくprivateにしてgetter、setter関数を定義して呼び出す意味とは?

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

0クリップ

投稿2018/09/06 17:52

クラスのメンバー変数をわざわざpublicじゃなくprivateにしてgetter、setter関数を定義して呼び出す意味がなんでかわかりません。

python

1class MyClass: 2 def __init__(self): 3 self._x = 12345 4 @property 5 def x(self): 6 return self._x 7 @x.setter 8 def x(self,x): 9 self._x = x 10instance = MyClass() 11print(instance.x) 12

これはクラスの変数をプライベートにしてgetter、setter変数を介して変数にアクセスできるようにしています。

python

1class MyClass: 2 def __init__(self): 3 self.x = 12345 4instance = MyClass() 5print(instance.x)

しかし、わざわざわかりにくく書かなくても最初からprivateなんてせずにこう書けばいいんじゃないかと思ってしまいます。
以前、PHPの勉強をしている時このような書き方を見た時はあまり意義がわからず、放置していたのですが、pythonでも出て来て、なぜこのような煩わしい書き方をするのかはっきりさせておきたいと思いました。
わかる方、教えてください。よろしくお願いします。

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

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

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

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

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

guest

回答6

0

例えば人を表すクラスを考えるとします。身長と体重が必要ですかね。
言うまでもなく、身長と体重は負の数になることはあり得ません。

もし、人クラスの身長が public だったら、負の数を設定しても、設定した時点でそれを検知することもできません。private で setter があれば、設定しようとする値をチェックして、明らかにおかしな値(負数だったり250cm超えてたり)だったら、設定させないとか例外を生成するとか、整合性を保つことができるのです。

メンバ変数だと冗長に思えるかも知れませんが、プロパティの概念のある言語だと、通常の代入のように見えて実は setter が呼ばれたりして、可読性がよく堅固なコードを記述できます。

投稿2018/09/06 23:52

tacsheaven

総合スコア13703

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

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

0

ベストアンサー

とりあえず思いついたものから。

①getter/setter片方だけを実装することができます。

読み出せるが、書き換えることができないようにしたり、
書き換えられるが今あるものを読み出せないようにしたり。

②挙動を付け加えることができます。

書き換えた時にログを残しておいたり、
読みだす時に、バリデーションをかけたり。

投稿2018/09/06 21:37

mkgrei

総合スコア8560

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

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

tachikoma

2018/09/06 22:06

②はクラスの振る舞いを変えずにリファクタリングする時に便利。
guest

0

アンダーバーを付けたメンバー変数をprivateと呼ぶ回答が多いので補足的な意味合いで回答します。

Pythonにはいわゆるprivateは存在せず、アンダーバーから始まる変数はモジュールやクラスの内部用であることを慣習的に示しているに過ぎません。例えば、_xとしてもinstance._xでアクセスできます。ただし、__xのようにアンダーバーを先頭に2つ以上付けるとname manglingと呼ばれる機能にアクセスしにくくなります。

投稿2018/09/07 06:47

tachikoma

総合スコア3601

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

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

退会済みユーザー

退会済みユーザー

2018/09/07 07:51

なるほど、確かにそうなってますね。 慣習的にということは、実質的な意味においてはプロパティの先頭に_をつけることは何も効果が無いということでしょうか?
tachikoma

2018/09/07 11:23

tabキーなどによるコード補完機能で頭に_が一つのものは表示しないというルールがある程度ですね。
LouiS0616

2018/09/07 11:31

後は * を用いたimportにも影響しますね。 まあこれも from module import _spam とか明示的に書かれては無力なわけですが。
tachikoma

2018/09/07 12:12

それがありましたか。フォローありがとうございます。
guest

0

こういう仕組みって、一回動いたらOKというプログラムを書くだけ(例えばプログラミングを学び始めた時など・・・)なら、まったくありがたみがわからないように思います。

一度書いたプログラムの処理改善や、機能追加をする時、一部分の変更が、いろんなところに影響して、芋づる式に変更箇所が増えていくと、「修正するより作り直した方が・・・」という事になってしまいます。

毎度、リニューアルしていては大変ですので、そうならないように、できるだけメンテナンスしやすいプログラムを書くための仕組み、知恵だと思います。

たとえば、MyClass.xは数値が代入される変数だとすると、それを参照する外部のロジックも当然、数値として扱うことになります。

その後、MyClassにある機能追加をしようとした時、MyClass.xの値は、文字列で持った方が都合が良いことがわかった時、直接参照されていると、すべての外部ロジックも文字列を扱うよう編集しなければならなくなります。

getter(プロパティ)としてMyClass.xを提供していれば、MyClass._xとして、文字列を持ち、MyClass.xとしては、MyClass._xを数値に変換した値を渡すことができるので、より影響が少なく変更を行えます。

外部ロジックから、MyClass.xに数値が代入された時も、setterで、MyClass._xに文字列変換して格納することで、内部処理の都合にも合わせることができます。

投稿2018/09/07 05:28

Meganezaru

総合スコア715

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

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

0

すべて自分で書いて、覚えているということであればあんまり意味はありません。
役に立つのは、ほかの人と共同で書くようになった時や、長くて複雑なコードを書くときです。
public にしておけば確かにすべての場所からアクセスできるので便利なんですが、逆に言えばすべての場所から好きにいじれるということです。
コンプライアンス的に変数の中身を教えたくない、勝手に変数の中をいじられたくない、いじられると壊れてしまう。
などといったときにprivateにしておけば外部からのアクセスはgetterとsetterを通してでしかアクセスできなくなります。

ほかの人も言っていた通り、冗長性を高める目的でprivateは使うこと多いです。

投稿2018/09/07 05:46

sitoa

総合スコア54

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

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

0

誰かがinstance.xに変な値を代入しちゃうかもしれません。あるいは、気軽にprintしてみたらパスワードとか機密情報が入っていて大変、とか。

また、外から見ると一つの状態に見えるだけで、内部的には変更があるたびに整合を取るための処理が走るとかのパターンも……(いやだな、それ)。

実際問題としては、基本的にpythonはゆるいので、有名ライブラリでもself.x的な(publicにする)方法で済ませているものはたくさんあります。要求される安全性の水準が高くなくて、プロパティにする他の動機(便利に使えるとか)がなければやらなくても良いとは思います。

投稿2018/09/06 22:23

hayataka2049

総合スコア30933

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問