@singledispatch
でできるかと思えば、第一引数の型でしか割当出来ない仕様なので、第一引数がselfの__init__
には使えない
結論
僕がPython慣れてないだけだけだった
defaultValueを使えばいい
#coding: utf-8
class Pokemon(object):
def __init__(self, id=25, name="ピカチュウ"):
self._id = id
self._name = name
def __str__(self):
return "Pokemon<{0._id}, {0._name}>".format(self)
pika = Pokemon()
print(pika)
mew = Pokemon(151, "ミュウ")
print(mew)
Pokemon<25, ピカチュウ>
Pokemon<151, ミュウ>
Python慣れないなあ・・・
でも
パラメータごとなら受け取れるけど、例えば他のクラスのインスタンス受け取ってでも初期化、みたいにしたかったらかなり面倒になる
他の値を捨てる感じ。
#coding: utf-8
class Zukan(object):
def __init__(self, page_id, title):
self._page_id = page_id
self._title = title
class Pokemon(object):
def __init__(self, id=25, name="ピカチュウ", zukan=None):
if zukan:
self._id = zukan._page_id
self._name = zukan._title
else:
self._id = id
self._name = name
def __str__(self):
return "Pokemon<{0._id}, {0._name}>".format(self)
pika = Pokemon()
print(pika)
mew = Pokemon(151, "ミュウ")
print(mew)
mew2 = Pokemon(zukan=Zukan(150, "ミュウツー"))
print(mew2)
Pokemon<25, ピカチュウ>
Pokemon<151, ミュウ>
Pokemon<150, ミュウツー>
こんな感じかなあ
あえて全ての引数のデフォルト値をNoneにしておいて、イニシャライズ時に引数名を必ず書くような規約にしても良いかもしれない
of(Java風に)
上のやつみたいにするなら、わざわざイニシャライザでディスパッチしなくてもいい感ある
たとえばOptional.ofとか、ImmutableMap.of()
みたいな感じで、builderメソッドを追加したほうがキレイかもしれない
#coding: utf-8
class Zukan(object):
def __init__(self, page_id, title):
self._page_id = page_id
self._title = title
class Pokemon(object):
def __init__(self, id=25, name="ピカチュウ"):
self._id = id
self._name = name
def __str__(self):
return "Pokemon<{0._id}, {0._name}>".format(self)
@staticmethod
def createFromZukan(zukan):
instance = Pokemon(zukan._page_id, zukan._title)
return instance
pika = Pokemon()
print(pika)
mew = Pokemon(151, "ミュウ")
print(mew)
mew2 = Pokemon.createFromZukan(Zukan(150, "ミュウツー"))
print(mew2)
サブクラスにする
コメントで、サブクラスにする、という手段も教えていただきました。
class Rect(object):
def __init__(self, x, y, width, height):
self.x, self.y, self.width, self.height = x, y, width, height
def __str__(self):
return '(%s, %s, %s, %s)' % (self.x, self.y, self.width, self.height)
def __repr__(self):
return 'Rect(%s, %s, %s, %s)' % (self.x, self.y, self.width, self.height)
class RectOfPointSize(Rect):
def __init__(self, point, size):
super(RectOfPointSize, self).__init__(point.x, point.y, size.width, size.height)
def __repr__(self):
return 'RectOfPointSize(Point(%s, %s), Size(%s, %s))' % (self.x, self.y, self.width, self.height)
class RectOfPointPoint(Rect):
def __init__(self, point, size):
super(RectOfPointPoint, self).__init__(point.x, point.y, size.x, size.y)
def __repr__(self):
return 'RectOfPointPoint(Point(%s, %s), Point(%s, %s))' % (self.x, self.y, self.width, self.height)
class Object(object): pass
point = Object()
point.x = 5
point.y = 6
size = Object()
size.width = 7
size.height = 8
r1 = Rect(1, 2, 3, 4)
r2 = RectOfPointSize(point, size)
r3 = RectOfPointPoint(point, point)
print r1, r2, r3
print repr(r1), repr(r2), repr(r3)
基底クラスはprivateか何かにおいて、サブクラスのみを使うのも、特に生成のあたりの可読性が高いのでこれもいいですね
その他
ディクショナリから作るなら
引数にするときに、ディクショナリをタプルに展開してイニシャライザ引数に渡すのもキレイ
おわりに
趣味の世界になってきた
もっと良い実装あれば教えて下さい