2013-05-16 4 views
5

なぜPythonで使用されているクラス外で関数を宣言する必要がありますか?Pythonプログラムでクラス外の関数を定義するとどんな利点がありますか

たとえば、following project on Githubは、_hash,_task_from_taskline、および_tasklines_from_tasksの機能でこれを行います。

class UnknownPrefix(Exception): 
"""Raised when trying to use a prefix that does not match any tasks.""" 
def __init__(self, prefix): 
    super(UnknownPrefix, self).__init__() 
    self.prefix = prefix 


def _hash(text): 

    return hashlib.sha1(text).hexdigest() 

def _task_from_taskline(taskline): 
    """ 
    snipped out actual code 
    """ 
    return task 

def _tasklines_from_tasks(tasks): 
    """Parse a list of tasks into tasklines suitable for writing.""" 


    return tasklines 

しかし、私は、これらの機能は、クラスTaskDictとの関係を持っていると思う:フォーマットは、次のと同じです。

なぜそれらをクラスから外しましたか?クラス外で宣言することの利点は何ですか?

+1

電源を入れ、それを持っている:どのような利点が代わりにクラスでそれらを置くことだろうか? –

+0

@MartijnPietersカプセル化。 –

+0

@ GeorgeStocker:関数がインスタンス状態に影響しない場合はどうなりますか? –

答えて

3

Stop Writing Classes PyConの話は、まさにこのテーマではありませんが、私はここに関連する授業です何を感じる含まれています:基本的に、アイデアはクラスはオブジェクトを作成するためのものであるということです。すべての属性、インスタンスメソッド、およびクラスメソッドは、オブジェクトを作成したり、オブジェクトを機能させたりするという目標をさらに進める必要があります。クラスは(この理論の下で)コード構成のためのものではありません - これがモジュールのためのものです。

これは非常に有力な戦略であり、誰もそれに同意するわけではありません。しかし、この文脈であなたの事例を考えるならば、関数がクラスの一部ではない理由は、関数がクラスによって使用されていても、オブジェクト上で実際に動作しないか、任意のオブジェクトの直接。これらは単に特定のクラスに束縛されていないユーティリティ関数であり、理論的にはライブラリ内の他の場所でも使用できます。

なぜ、なぜクラスに入れないのですか?それは、クラスがコードの編成に使用されるべきかどうかを信じるかどうかにかかっています。この場合、著者は明らかに、クラスではなくコードの編成のためのモジュールであるという考えを買った。

0

通常、関数をどこに配置するかを決めるときに、関数を使用することを認識することが重要です。それらがクラスの内部にあり、プログラムの他の部分で使用されることはない場合は、それらをクラスに入れるのが理にかなっています。しかし、他の部品がそれらを使用する可能性が最も高い場合は、モジュールレベルにする必要があります。

+0

はい、私は、私はその機能がクラスに属していると思っていて、クラス外の人には使われません。だから私はなぜクラスを定義するのか疑問に思う。 – poleworld

1

定義されている関数がすべてオブジェクト内のデータに対して機能する場合は、関数をクラスレベルにカプセル化することだけが有効です。また、クラスがそれらの関数を呼び出す唯一のものであることを見て、これらをクラスに入れるのは意味があります。

クラスの外側に配置する唯一の利点は、クラス自体とは無関係のこれらの関数を使用する他のコードがある場合です。他のモジュールで使用されるいくつかのヘルパー関数を構築している場合。

3
  1. は、彼らは、インポートが容易であり、メンバ関数は、クラスに入れた場合でも
  2. より短い名前を持って、彼らはおそらく、とにかくstaticmethodクラスメソッド/ことになるだろう。
  3. Pythonコードではダックタイピングを使用しています。メソッドはそのクラスでしか使用できないことを暗示しますが、実際にはコードはそれより汎用的です。
  4. 個人の好み。一部の人々は、「ドメインモデル」と「ビジネスロジック」を分離することを好んでいました。

最後に、この特定のプログラムでは、どちらの方法でも利点や不利な点はありません。

+0

はい、私に。私はそれらをクラスに入れ、staticmethodとして定義します。 – poleworld

1

機能は、小規模なパフォーマンス上の利点に周り

>>> import timeit 
>>> timeit.Timer('foo()', 'def foo(): return 1').timeit() 
0.09944701194763184 
>>> timeit.Timer('A.foo()', ''' 
... class A(object): 
...  @staticmethod 
...  def foo(): 
...   return 1''').timeit() 
0.12048101425170898 
関連する問題