Python property() 関数
property()Python で属性(property)を作成するために使用される組み込み関数です。
property は強力なメカニズムであり、属性にアクセスする際にコードを実行することを可能にします。計算プロパティ、データ検証などの高度な機能を実装するためによく使用されます。
単語の意味: property 意为"属性",用于定义类的属性。
基本構文とパラメータ
構文形式
property(fget=None, fset=None, fdel=None, doc=None)
パラメータの説明
- パラメータ fget(オプション):
- 型: 関数
- 説明: 属性の値を取得するときに呼び出される関数。
- パラメータ fset(オプション):
- 型: 関数
- 説明: 属性の値を設定するときに呼び出される関数。
- パラメータ fdel(オプション):
- 型: 関数
- 説明: 属性を削除するときに呼び出される関数。
- パラメータ doc(オプション):
- 型: 文字列
- 説明: プロパティの docstring(ドキュメント文字列)。
関数の説明
- 戻り値: property オブジェクトを返します。
- 特徴: 属性へのアクセスを通常の変数のように見せますが、実際には関数を実行します。
例
例1:基本的な使い方
例
class Circle:
def __init__(self, radius):
self.radius = radius
# property を使用して計算プロパティを作成
def get_area(self):
"""円の面積を計算"""
return 3.14159 * self.radius ** 2
def set_radius(self, value):
"""半径を設定(検証を追加可能)"""
if value < 0:
raise ValueError("半径は負の数にできません")
self.radius = value
# property を作成
area = property(get_area, set_radius)
# 使用
c = Circle(5)
print(f"半径: {c.radius}") # 出力: 半径: 5
print(f"面積: {c.area}") # 出力: 面積: 78.53975
# 属性を設定
c.radius = 10
print(f"新しい面積: {c.area}") # 出力: 新しい面積: 314.159
# 検証
c.radius = -5 # 例外が発生します
def __init__(self, radius):
self.radius = radius
# property を使用して計算プロパティを作成
def get_area(self):
"""円の面積を計算"""
return 3.14159 * self.radius ** 2
def set_radius(self, value):
"""半径を設定(検証を追加可能)"""
if value < 0:
raise ValueError("半径は負の数にできません")
self.radius = value
# property を作成
area = property(get_area, set_radius)
# 使用
c = Circle(5)
print(f"半径: {c.radius}") # 出力: 半径: 5
print(f"面積: {c.area}") # 出力: 面積: 78.53975
# 属性を設定
c.radius = 10
print(f"新しい面積: {c.area}") # 出力: 新しい面積: 314.159
# 検証
c.radius = -5 # 例外が発生します
期待される実行結果:
半径: 5 面积: 78.53975 新面积: 314.159
コード解析:
- property を使用して計算プロパティを定義できます。
- setter でデータ検証ロジックを追加できます。
例2:@property デコレータを使う(推奨)
例
class Student:
def __init__(self, name, score):
self.name = name
self._score = score
@property
def score(self):
"""成績を取得"""
return self._score
@score.setter
def score(self, value):
"""成績を設定(検証付き)"""
if not 0 <= value <= 100:
raise ValueError("成績は 0 から 100 の間でなければなりません")
self._score = value
@property
def grade(self):
"""成績に基づいて等級を計算"""
if self._score >= 90:
return 'A'
elif self._score >= 80:
return 'B'
elif self._score >= 70:
return 'C'
elif self._score >= 60:
return 'D'
else:
return 'F'
# 使用
s = Student("Tom", 85)
print(s.name) # 出力: Tom
print(s.score) # 出力: 85
print(s.grade) # 出力: B
s.score = 92 # 成績を設定
print(s.grade) # 出力: A
s.score = 105 # 例外が発生します
def __init__(self, name, score):
self.name = name
self._score = score
@property
def score(self):
"""成績を取得"""
return self._score
@score.setter
def score(self, value):
"""成績を設定(検証付き)"""
if not 0 <= value <= 100:
raise ValueError("成績は 0 から 100 の間でなければなりません")
self._score = value
@property
def grade(self):
"""成績に基づいて等級を計算"""
if self._score >= 90:
return 'A'
elif self._score >= 80:
return 'B'
elif self._score >= 70:
return 'C'
elif self._score >= 60:
return 'D'
else:
return 'F'
# 使用
s = Student("Tom", 85)
print(s.name) # 出力: Tom
print(s.score) # 出力: 85
print(s.grade) # 出力: B
s.score = 92 # 成績を設定
print(s.grade) # 出力: A
s.score = 105 # 例外が発生します
期待される実行結果:
Tom 85 B A
コード解析:
- @property デコレータはより Pythonic な書き方です。
- getter、setter、deleter を定義できます。
例3:読み取り専用プロパティ
例
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
"""読み取り専用プロパティ"""
return self._name
# setter を定義しない場合、属性は変更できません
p = Person("Tom")
print(p.name) # 出力: Tom
# 変更しようとするとエラーになります(setter がないため)
# p.name = "Jack" # AttributeError が発生します
# 削除してもエラーになります
# del p.name # AttributeError が発生します
def __init__(self, name):
self._name = name
@property
def name(self):
"""読み取り専用プロパティ"""
return self._name
# setter を定義しない場合、属性は変更できません
p = Person("Tom")
print(p.name) # 出力: Tom
# 変更しようとするとエラーになります(setter がないため)
# p.name = "Jack" # AttributeError が発生します
# 削除してもエラーになります
# del p.name # AttributeError が発生します
期待される実行結果:
Tom
getter だけを定義して setter を定義しないと、読み取り専用プロパティを作成できます。
その他の拡張