2013-02-27 5 views
13

興味があるだけ、LEN()を使用し、デフ__len __(自己):クラスを構築する

は、私はクラスをビルドするときlen()またはdef __len__()を使用しての間に違い(長所と短所)はありますか?そして、これは最高のPythonスタイルですか?

class foo(object): 
     def __init__(self,obs=[]) 
     self.data = obs 
     self.max = max(obs) 
     self.min = min(obs) 
     self.len = len(obs) 

または

class foo(object): 
     def __init__(self,obs=[]) 
     self.data = obs 
     self.max = max(obs) 
     self.min = min(obs) 
     def __len__(self): 
     return len(self.data) 
+1

第1のものと第2のものはどのように等価でしょうか? –

+6

あなたが何をしているのか分からない限り、キーワードパラメータのデフォルト値として '[]'を使用しないでください。 [Python:変更可能なデフォルト引数]の「最小驚き」(http://stackoverflow.com/q/1132941)を参照してください。 –

答えて

25

巨大違いがあります。

__len__()メソッドはフックメソッドです。 len()ファンクションは、存在する場合はオブジェクトの長さを照会するために__len__メソッドを使用します。 通常 APIの人々が使用することを期待

はその基準から外れるだろう代わりに.len属性を使用して、len()方法です。

self.dataの長さが変更されることが予想されない場合は、属性に長さをキャッシュし、.__len__()にその属性を返すことができます。

class foo(object): 
    def __init__(self, obs=None): 
     if obs is None: # provide a default if no list was passed in. 
      obs = [] 
     self.data = obs 
     self.max = max(obs) 
     self.min = min(obs) 
     self._data_len = len(obs) 

    def __len__(self): 
     return self._data_len 
6

いくつかの違いがあります。

  1. のみ第二のアプローチはfooのためにあなたに馴染みlen(obj)構文を与えるだろうが。最初はobj.len()が必要です。
  2. 長さがself.dataの場合、工事後に変更することができますが、2番目のバージョンのみが新しい長さを反映します。
関連する問題