我想对我的第一个使用OOP样式的Python脚本提供一些反馈。这是一个Munin插件,根据插件名称(dell_fans,dell_temps)显示平均风扇速度或平均机箱温度。
大约一小时前我将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 :(得分:2)
Temps
是FanSpeed
吗?这是对子类化是否合适的试金石(例如,大象是动物,汽车不是动物 - 所以可能适合使用Animal
的子类来模拟大象,但不是{的子类{1}}为汽车建模。
听起来他们正在为两个不同的东西建模 - 所以是的,为它们创建一个共同的基类。
答案 1 :(得分:1)
一种更合适的方式是定义一个主类(例如,FanStatistics
或任何你想要调用的类),在其中定义一般方法,如average
方法,以及将其子类化为FanSpeed
和FanTemp
。这样你就不会混淆名称,因为温度不是速度的子类或特化 - 但速度和温度都是抽象统计数据的特化。
答案 2 :(得分: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