Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Pythonにはデコレータというものがありますが、その中でもともと標準で用意されているデコレータとして次の3つが有名です。
今回はこのプロパティ(@property)について、その基本的な考え方と使い方、そして使い場合のメリットについて解説します。
Contents
@propertyとはクラス内部で定義されたメソッドを、属性として使えるようにするデコレータの1種です。
Pythonのデコレータについてはこれまでいくつかの解説記事を書きました。たとえば次の3つの記事をご覧ください。
これだけでは当然よくわからないので、@propertyなしの普通のクラスを使う場合と、@propertyありのクラスを使う場合との違いを見ていきましょう。
class C_1:
def __init__(self, name: str):
self.name = name
def print_name(self):
print(self.name)
c_1 = C_1("Tom")
# インスタンスの属性、nameを取得
c_1.name # ==> 'Tom'
# インスタンスのメソッド、print_nameを実行
c_1.print_name() # ==> Tom
普通クラスを使う場合は、そのインスタンスの属性の情報を取得するときは、
目的 | 記述方法 |
---|---|
インスタンスの属性の情報を取得 | インスタンス名.属性名 |
インスタンスのメソッドを実行 | インスタンス名.メソッド名() |
このように、メソッドを実行するときは「()」をつけます。
しかし@propertyを使ったメソッドについては、「()」をつけずに記述・実行することが可能となります。つまり、属性の場合と同じ書き方ができます。そこで次に@propertyが存在するクラスの場合の使い方を見ていきましょう。
class C_2:
def __init__(self, name: str):
self.name = name
@property
def print_name(self):
print(self.name)
c_2 = C_2("Tom")
# インスタンスの属性、nameを取得
c_2.name # ==> 'Tom'
# @propertyを使ったメソッドを実行:「()」が不要
c_2.print_name # ==> Tom
上述のように、
c_2.print_name
の部分の書き方に注意してください。メソッドのはずなのに、「()」がありません。それでもきちんとそのメソッドが実行されています。
ではこのような@propertyに一体どのようなメリットがあるのでしょうか。
@propertyを使うメリットはいくつかあるでしょうが、その1つとして言えるのはまさに上で書いたように「属性の情報を取得する場合と同じ形で書ける」という点です。
これを説明するため次のコードを見てください。
class C_3():
# __init__の中は、メソッドを使わない純粋な代入文のみでシンプルな内容
def __init__(self, product_name):
self.product_name = product_name
# 価格についてはこのメソッドで処理
@property
def price(self):
if self.product_name == "Nike Panda":
return 15000
else:
return 5000
c_3 = C_3("Nike Panda")
c_3.product_name # ==> 'Nike Panda'
c_3.price # ==> 15000
このコードにおいて、クラスC_3はスニーカーという物体の情報だと思ってください。そのインスタンスであるc_3はスニーカーなので、普通は
という2つの情報を持っているでしょう。そこで上のコードでもその2つの情報を登録しています。
そして価格については、
とインスタンス生成後の初期化処理において場合分けを行っています。
この処理を、__init__メソッド内部で書いてもエラーになるわけではありません。しかし、Pythonの流儀・哲学として__init__メソッド内部の処理は、できるだけ単純な内容であることが良いとされています。極論すれば、__init__内部は上のコードのような単純でシンプルな代入文だけにしましょうということです。
したがって条件によって代入されるデータが変わるような処理は__init__内部に書かず、その外側に出してしまおうというわけです。これで__init__はシンプルな見た目となり、後でコードを読むときに見やすく、そして__init__の処理が理解しやすくなります。可読性があがります。
また価格情報については、「製品名と製品価格」という概念に対応させ、「name」「price」という単純な名詞形にしたいですね。
そこで、
という名前すると見た目の統一感が出ますし、コードの意味も素早く理解できるでしょう。
このうち「c_3.price」については、見た目は価格情報を格納している「属性」ですが、実質的には「複数の条件によって分岐させるメソッド」です。ですが@propertyを使うとメソッドであるという実質を隠して、純粋な属性であるnameと並ぶ、同種の属性であるかのように見せかけることができます。
@propertyを使うメリットの1つというのは、このように他の属性との関係で見た目の統一感を作り出し、コードの可読性や理解のしやすさを手助けするという点にあります。
またクラス内部で使われるデコレータの他種であるクラスメソッド(@classmethod)とスタティックメソッド(@staticmethod)については次の記事で解説を書いていますので、ぜひご覧ください。
Pythonの基礎を効率よく学習するには、やはりただ本を読むだけよりも動画による学習がわかりやすくておすすめです。
特に世界最大の動画学習サイトのUdemy(ユーデミー)では現役エンジニアによる人気講座が多数あります。その中でも人気のものを5つ紹介したのが次の記事です。