質問は、技術的な背景についてではなく、どのユースケースで使用するのが好ましいかについて言及しています。
Python では、プロパティ、記述子、またはマジック メソッドを介して属性へのアクセスを制御できます。どのユースケースで最もpythonicですか? それらはすべて同じ効果があるようです (以下の例を参照)。
私は次のような答えを探しています:
- プロパティ: …の場合に使用する必要があります</li>
- Descriptor : …の場合、プロパティの代わりに使用する必要があります。
- 魔法の方法: …の場合にのみ使用してください。
例
ユース ケースは、メソッドで設定できない可能性がある属性です__init__
。たとえば、オブジェクトがまだデータベースに存在していないが、後で存在する場合などです。属性にアクセスするたびに、設定して返すように試行する必要があります。
Python シェルで Copy&Paste を使用する例として、2 回目に要求されたときにのみ属性を表示するクラスがあります。それで、どちらが最善の方法ですか、またはそれらのいずれかが望ましいさまざまな状況がありますか? 実装方法は次の 3 つです。
プロパティ付き::
class ContactBook(object):
intents = 0
def __init__(self):
self.__first_person = None
def get_first_person(self):
ContactBook.intents += 1
if self.__first_person is None:
if ContactBook.intents > 1:
value = 'Mr. First'
self.__first_person = value
else:
return None
return self.__first_person
def set_first_person(self, value):
self.__first_person = value
first_person = property(get_first_person, set_first_person)
と__getattribute__
::
class ContactBook(object):
intents = 0
def __init__(self):
self.first_person = None
def __getattribute__(self, name):
if name == 'first_person' \
and object.__getattribute__(self, name) is None:
ContactBook.intents += 1
if ContactBook.intents > 1:
value = 'Mr. First'
self.first_person = value
else:
value = None
else:
value = object.__getattribute__(self, name)
return value
記述子::
class FirstPerson(object):
def __init__(self, value=None):
self.value = None
def __get__(self, instance, owner):
if self.value is None:
ContactBook.intents += 1
if ContactBook.intents > 1:
self.value = 'Mr. First'
else:
return None
return self.value
class ContactBook(object):
intents = 0
first_person = FirstPerson()
それぞれに次の動作があります::
book = ContactBook()
print(book.first_person)
# >>None
print(book.first_person)
# >>Mr. First