2017-09-28 20 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將從課外被調用。這是定義相關功能的正確方法。使用classmethodsstaticmethods或創建該類的對象,然後調用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() 

只有這種方法的con是,你必須強制通過模塊導入的這個慣例名稱而不是功能。

2

當方法需要類信息,即訪問類屬性時,使用@classmethod。 (讓我們說的health_monitor類有OS屬性,這會影響你執行的命令)

使用@staticmethod當方法不需要它在聲明的類的任何數據;像你所有的功能一樣。

我經常發現自己使用staticmethod因爲我把一類內爲簡單起見功能,因爲它們是我的同班同學上下文運行,但它不中繼。

至於你類:當你所有的方法都是classmethodsstaticmethods,你應該考慮駐留在模塊範圍的代碼,而不是一類。爲什麼?好吧,如果他們之間沒有共享任何數據,沒有理由將他們分組在課堂上。它會更簡單:

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

# main.py 
health_monitor.get_uptime() 
相關問題