2017-09-28 11 views
-1

私はマシンの正常性統計を返すクラスを持っています。Python - staticmethod vs classmethod

class HealthMonitor(object): 
    """Various HealthMonitor methods.""" 

    @classmethod 
    def get_uptime(cls): 
     """Get the uptime of the system.""" 
     return uptime() 

    @classmethod 
    def detect_platform(cls): 
     """Platform detection.""" 
     return platform.system() 

    @classmethod 
    def get_cpu_usage(cls): 
     """Return CPU percentage of each core.""" 
     return psutil.cpu_percent(interval=1, percpu=True) 

    @classmethod 
    def get_memory_usage(cls): 
     """Return current memory usage of a machine.""" 
     memory = psutil.virtual_memory() 
     return { 
      'used': memory.used, 
      'total': memory.total, 
      'available': memory.available, 
      'free': memory.free, 
      'percentage': memory.percentage 
     } 

    @classmethod 
    def get_stats(cls): 
     return { 
      'memory_usage': cls.get_memory_usage(), 
      'uptime': cls.uptime(), 
      'cpu_usage': cls.get_cpu_usage(), 
      'security_logs': cls.get_windows_security_logs() 
     } 

get_statsはクラス外から呼び出されます。これは、関連する関数を定義する正しい方法です。 classmethodsまたはstaticmethodsを使用するか、クラスのオブジェクトを作成してget_statsを呼び出します。

私はその相違点について十分に読んだことがありますが、例で私の理解を明確にしたいと思います。どちらがもっとpythonicなアプローチですか?

+5

正直な質問:なぜあなたはクラスをまったく使っていますか?これまでインスタンス化しているとは思われません。私はどんな状態も見ません。なぜ機能のコレクションだけではないのですか? – glibdud

+0

'@ classmethod'と' @ staticmethod'は異なるものです。彼らは交換できません。 '@ staticmethod'はクラスと関数を論理的にグループ化したいが、関数は状態を必要としないときに使うべきです。 '@ classmethod'は、他の言語のオーバーロードされたコンストラクタとして考えることができます。 –

+0

@glibdud - 私は特定のクラスの特定のドメインの機能をグループ化する方が好きです。 – PythonEnthusiast

答えて

2

まあ、classesは、基本的に、データをカプセル化します。つまり、そのオブジェクトを識別する特定のデータに対する一連の動作です。今では、あなたが定義したメソッドのどれも、特にクラスとは関係がありません。

したがって、これらのメソッド間でデータを共有する必要がない限り、classmethodsを使用することはまったく意味がありません。 static methodsを使用するほうが良いでしょうが、やはり名前空間を提供するだけです。ただhealth_monitor.pyという名前のファイルに簡単な機能として、すべてのメソッドを定義して、次のようにそれを使用することについてどのように -

import health_monitor 

uptime = health_monitor.get_uptime() 

このアプローチの唯一の詐欺は、モジュールによって輸入のこの規則を施行する必要があるだろうということです名前であり、機能ではありません。

2

メソッドがクラス情報を必要とする場合、つまりクラス属性にアクセスする場合は@classmethodを使用してください。この方法は、それがで宣言されたクラスの任意のデータを必要としない場合に使用します@staticmethod

(のはhealth_monitorクラスを使用すると、実行コマンドに影響を与える可能性があり、OS属性を持っていたとしましょう)。あなたのすべての機能のように。

私は、多くの場合、彼らは私のクラスにコンテキストでを実行しているので、自分自身が、私はシンプルのクラスの内側に置くの機能にstaticmethodを使用見つけるが、それには中継しません。すべてのメソッドがclassmethodsまたはstaticmethodsているとき、あなたはモジュール範囲内のコードではなく、クラスの存在を検討してください:あなたのクラスについては

。どうして?彼らの間でデータを共有していなければ、クラスにグループ化する理由はありません。

# health_monitor.py 
def get_uptime(cls): 
    """Get the uptime of the system.""" 
    return uptime() 

# main.py 
health_monitor.get_uptime() 
関連する問題