Pythonでは、属性に直接割り当てるか、属性の状態を変更するメソッド呼び出しを行うことで、インスタンスの状態を変更できます。
foo.thing = 'baz'
また:
foo.thing('baz')
このように動作する多数の属性にスケーリングする上記の両方の形式を受け入れるクラスを作成するための優れた方法はありますか?(簡単に、私が特に気に入らない実装の例を示します。)これがばかげたAPIだと思っているなら、私に知らせてください。しかし、おそらくもっと具体的な例が必要です。Document
クラス があるとしましょう。Document
属性を持つことができますtitle
。ただし、title
いくつかの状態(font、fontsize、justification、...)も必要な場合がありますが、平均的なユーザーは、タイトルを文字列に設定してそれを実行するだけで十分満足できる場合があります...
これを実現する1つの方法は、次のとおりです。
class Title(object):
def __init__(self,text,font='times',size=12):
self.text = text
self.font = font
self.size = size
def __call__(self,*text,**kwargs):
if(text):
self.text = text[0]
for k,v in kwargs.items():
setattr(self,k,v)
def __str__(self):
return '<title font={font}, size={size}>{text}</title>'.format(text=self.text,size=self.size,font=self.font)
class Document(object):
_special_attr = set(['title'])
def __setattr__(self,k,v):
if k in self._special_attr and hasattr(self,k):
getattr(self,k)(v)
else:
object.__setattr__(self,k,v)
def __init__(self,text="",title=""):
self.title = Title(title)
self.text = text
def __str__(self):
return str(self.title)+'<body>'+self.text+'</body>'
これで、これを次のように使用できます。
doc = Document()
doc.title = "Hello World"
print (str(doc))
doc.title("Goodbye World",font="Helvetica")
print (str(doc))
ただし、この実装は少し厄介なようです(with __special_attr
)。たぶん、これはめちゃくちゃなAPIだからです。わからない。 これを行うためのより良い方法はありますか? それとも、私はこれに少し行き過ぎた道を残しましたか?
これにも使用できることは@property
わかっていますが、このように動作する属性が複数ある場合は、まったく拡張できません。それぞれにゲッターとセッターを作成する必要があります。