2017-09-28 19 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() 
相关问题