Pythonで複数のコンストラクタを異なる署名で定義することはできませんか?そうでない場合、それを回避する一般的な方法は何ですか?
たとえば、クラスCity
を定義したいとします
someCity = City()
またはsomeCity = City("Berlin")
と言いたいのですが、最初の名前はデフォルトの名前の値を与え、2番目はそれを定義します。
Javaとは異なり、複数のコンストラクターを定義することはできません。ただし、デフォルト値が渡されない場合は、デフォルト値を定義できます。
def __init__(self, city="Berlin"):
self.city = city
署名がnumberのみで異なる場合、デフォルトの引数を使用するのが正しい方法です。引数の異なるkindsを渡すことができるようにしたい場合は、キーワード引数を使用する代わりに、別の回答で言及されているisinstance
ベースのアプローチを避けようとします。キーワード引数のみを使用すると扱いにくい場合は、クラスメソッドと組み合わせることができます(bzrlibコードはこのアプローチを好む)。これは馬鹿げた例に過ぎませんが、アイデアが得られることを願っています。
class C(object):
def __init__(self, fd):
# Assume fd is a file-like object.
self.fd = fd
@classmethod
def fromfilename(cls, name):
return cls(open(name, 'rb'))
# Now you can do:
c = C(fd)
# or:
c = C.fromfilename('a filename')
これらのクラスメソッドはすべて同じ__init__
を通過しますが、クラスメソッドを使用すると、__init__
へのキーワード引数の組み合わせを覚えるよりもはるかに便利です。
isinstance
は、Pythonのアヒルのタイピングにより実際に渡されたオブジェクトの種類を把握するのが難しいため、回避するのが最善です。たとえば、ファイル名またはファイルのようなオブジェクトを取得する場合、多くのファイルがあるためisinstance(arg, file)
file
をサブクラス化しないオブジェクト(urllib、StringIO、または...から返されるオブジェクトなど)。通常、異なるキーワード引数を使用して、どのようなオブジェクトが意図されているかを呼び出し元に明示的に通知することをお勧めします。
指定した例では、デフォルト値を使用します。
class City:
def __init__(self, name="Default City Name"):
...
...
一般に、2つのオプションがあります。
1)タイプに基づいてif
-Elif
ブロックを実行します。
def __init__(self, name):
if isinstance(name, str):
...
Elif isinstance(name, City):
...
...
2)アヒルのタイピングを使用します---つまり、クラスのユーザーがそれを正しく使用するのに十分な知性があると仮定します。これは通常、推奨されるオプションです。
最も簡単な方法は、キーワード引数を使用することです。
class City():
def __init__(self, city=None):
pass
someCity = City(city="Berlin")
これはかなり基本的なものです。多分 python docs ?
ジャックMは正しいです。次のようにします。
>>> class City:
... def __init__(self, city=None):
... self.city = city
... def __repr__(self):
... if self.city: return self.city
... return ''
...
>>> c = City('Berlin')
>>> print c
Berlin
>>> c = City()
>>> print c
>>>