web-dev-qa-db-ja.com

Pythonの複数のコンストラクタ?

可能性のある複製:
Pythonで複数のコンストラクターを使用するためのクリーンでPython的な方法は何ですか?

Pythonで複数のコンストラクタを異なる署名で定義することはできませんか?そうでない場合、それを回避する一般的な方法は何ですか?

たとえば、クラスCityを定義したいとします

someCity = City()またはsomeCity = City("Berlin")と言いたいのですが、最初の名前はデフォルトの名前の値を与え、2番目はそれを定義します。

178
Chris

Javaとは異なり、複数のコンストラクターを定義することはできません。ただし、デフォルト値が渡されない場合は、デフォルト値を定義できます。

def __init__(self, city="Berlin"):
  self.city = city
237
Andrew Sledge

署名が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、または...から返されるオブジェクトなど)。通常、異なるキーワード引数を使用して、どのようなオブジェクトが意図されているかを呼び出し元に明示的に通知することをお勧めします。

200
mzz

指定した例では、デフォルト値を使用します。

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)アヒルのタイピングを使用します---つまり、クラスのユーザーがそれを正しく使用するのに十分な知性があると仮定します。これは通常、推奨されるオプションです。

6
pavpanchekha

最も簡単な方法は、キーワード引数を使用することです。

class City():
  def __init__(self, city=None):
    pass

someCity = City(city="Berlin")

これはかなり基本的なものです。多分 python docs

4
Jack M.

ジャック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

>>>
4
telliott99