2010-02-03 58 views
2

我想对使用OOP风格的第一个Python脚本提供一些反馈。这是一个Munin插件,它根据插件的名称(dell_fans,dell_temps)绘制平均风扇速度或平均底盘温度。Python:第一个OOP风格脚本的反馈/更正

一个小时左右之前,我把风扇速度插件的submitted a procedural version换成了stackoverflow,以获得帮助将其转换为OOP风格。然后,我构建了这两个脚本的结合。任何反馈,建议,更正都会非常有帮助。我想在他们巩固之前纠正我可能有的任何错误观念。

更新:修改为具有公共基类。还有其他建议吗?

import sys 
import subprocess 

class Statistics(object): 

    def __init__(self, command): 
     self.command = command.split() 

    def average(self): 
     data = subprocess.Popen(self.command,stdout=subprocess.PIPE).stdout.readlines() 

     count = total = 0 
     for item in data: 
      if "Reading" in item: 
       # Extract variable length fan speed, without regex. 
       total += float(item.split(":")[1].split()[0]) 
       count += 1 
     # Sometimes omreport returns zero output if omsa services aren't started. 
     if not count or not total: 
      raise ValueError("No output from omreport. Is OMSA services started?") 

     avg = (total/count) 
     return avg 

    def print_autoconfig(self): 
     print "autoconfig goes here" 


class Fanspeed(Statistics): 

    def __init__(self, command): 
     Statistics.__init__(self, command) 

    def print_config(self): 
     print "graph_title Average Fan Speed" 
     print "graph_args --base 1000 -l 0" 
     print "graph_vlabel speed (RPM)" 
     print "graph_category Chassis" 
     print "graph_info This graph shows the average speed of all fans" 
     print "graph_period second" 
     print "data.label speed" 
     print "data.info Average fan speed for the five minutes." 


class Temps(Statistics): 

    def __init__(self, command): 
     Statistics.__init__(self, command) 

    def print_config(self): 
     print "graph_title Average Temperature" 
     print "graph_args --upper-limit 120 -l 0" 
     print "graph_vlabel Celsius" 
     print "graph_category Chassis" 
     print "graph_info This graph shows the avg temp of all sensors." 
     print "graph_period second" 
     print "data.label temp" 
     print "data.info Average chassis temperature for the five minutes." 


if __name__ == '__main__': 
    # Munin populates sys.argv[1] with "" (an empty argument), lets remove it. 
    sys.argv = [x for x in sys.argv if x] 

    if "fans" in sys.argv[0]: 
     cmd = "/usr/sbin/omreport chassis fans" 
     omdata = Fanspeed(cmd) 
    elif "temps" in sys.argv[0]: 
     cmd = "/usr/sbin/omreport chassis temps" 
     omdata = Temps(cmd) 
    else: 
     print >> sys.stderr, "Change filename to dell_fans or dell_temps." 
     sys.exit(1) 

    if len(sys.argv) > 1: 
     if sys.argv[1].lower() == "autoconfig": 
      omdata.print_autoconfig() 
     elif sys.argv[1].lower() == "config": 
      omdata.print_config() 
    else: 
     try: 
      average = omdata.average() 
      print "data.value %s" % average 
     except OSError, e: 
      print >> sys.stderr, "Error running '%s', %s" % (cmd, e) 
      sys.exit(1) 
     except ValueError, e: 
      # Sometimes omreport returns zero output if omsa services aren't started. 
      print >> sys.stderr, 'Error: "omreport chassis fans" returned 0 output.' 
      print >> sys.stderr, 'OMSA running? Try: "srvadmin-services.sh status".' 
      sys.exit(1) 
+0

感谢大家,你们所有人以及本网站对于像我这样的初学者来说都是一个宝贵的资源。 – CarpeNoctem 2010-02-03 12:44:48

回答

2

Temps a FanSpeed?这是检验子类化是否合适的试金石(例如,大象是动物,汽车不是动物 - 因此可能适合具有模拟大象的Animal的子类,而不是模拟汽车的Animal的子类)。

这听起来像他们正在建模两个不同的东西 - 所以是,为他们创建一个共同的基类。

+0

明白了,我会创建一个共同的基类(非常有意义)。还有其他建议吗? – CarpeNoctem 2010-02-03 12:08:27

1

一个语义上更合适的方法是定义一个主类(例如,FanStatistics或任何你想将它命名),其中定义的一般方法,如average方法,和子成FanSpeedFanTemp 。这样你就不会混淆名字,因为温度不是速度的子类或专业化 - 但速度和温度都是抽象统计数据的专业化。

1

这听起来像你有两种不同的统计数据,你想模型,风扇速度(Fanspeed)和温度(Temps)。如果你想在它们之间共享一些共同的功能,为它们创建公共的基类,例如可以称它为Statistic

class Statistic(object): 
    def average(self): 
     pass # your logic to calculate the average here 

class Fanspeed(Statistic): 
    pass # your fan speed functionaly here 

class Temps(Statistic): 
    pass # your temperature functionaly here 
+0

谢谢,我更新了脚本以使用通用基类。还有什么你看到的? – CarpeNoctem 2010-02-03 12:22:25