0

This description may be a bit complicated so I will try to keep it short.

I have the following code that is working correctly...

def singlelist():
    from datetime import datetime
    from subprocess import Popen
    from subprocess import PIPE
    output=Popen(["sar","-r"], stdout=PIPE).communicate()[0]
    date=datetime.now()
    date=str(date).split()[0]
    listtimeval=[]
    for line in output.split('\n'):
        if line == '' or 'Average' in line or 'kb' in line or 'Linux' in line or 'RESTART' in line:
            pass
        else:
            (time,ampm,field1,field2,field3,field4,field5,field6,field7) = line.split()
            listtimeval.append((time + " "+ ampm + "," + field3).split(','))
    updatelist= [ [str(date) + " " +x[0],x[1]] for x in listtimeval]
    return updatelist


val=singlelist()

...notice how time,ampm,etc are not defined previously...

I am trying to make this more dynamic as the output of sar will not always have the same number of columns.

What I want to do is this...

def fields(method):
    if method == '-r':
        nf = (time,ampm,field1,field2,field3,field4,field5,field6,field7)
    return nf


def singlelist(nf):
    from datetime import datetime
    from subprocess import Popen
    from subprocess import PIPE
    output=Popen(["sar","-r"], stdout=PIPE).communicate()[0]
    date=datetime.now()
    date=str(date).split()[0]
    listtimeval=[]
    for line in output.split('\n'):
        if line == '' or 'Average' in line or 'kb' in line or 'Linux' in line or 'RESTART' in line:
            pass
        else:
            nf = line.split()
            listtimeval.append((time + " "+ ampm + "," + field3).split(','))
    updatelist= [ [str(date) + " " +x[0],x[1]] for x in listtimeval]
    return updatelist

method='-r'
nf=fields(method)
val=singlelist(nf)

However I am getting this...

Traceback (most recent call last):
  File "./Logic.py", line 110, in <module>
    nf=fields(method)
  File "./Logic.py", line 58, in fields
    nf = (time,ampm,field1,field2,field3,field4,field5,field6,field7)
NameError: global name 'time' is not defined

How can I accomplish this?

4

2 回答 2

0

跟进皮埃尔的回答:您可以分配给未声明的变量(隐式创建它),如果没有未定义的变量错误,您不能分配 FROM 它。

您似乎还让那个糟糕的函数做了很多不相关的事情——加载模块、调用子进程、解析和重新解析数据。如果您将其分解如下,可能更容易理解和维护:

import datetime
from itertools import izip
from subprocess import Popen, PIPE

def call_sar(options, columns):
    sar  = Popen(["sar"]+options, stdout=PIPE)  # create subprocess
    res  = sar.communicate()[0]                 # get stdout text
    data = res.splitlines()[3:-1]               # grab the relevant lines
    return (dict(izip(columns, row.split())) for row in data)

def get_system_stats(mode, fmt=None):
    modes = {   # different ways to call sar, and the values returned by each
        "all_cpus": ('-r',    'time ampm cpu user_pct nice_pct system_pct iowait_pct steal_pct idle_pct'),
        "each_cpu": ('-P',    'time ampm cpu user_pct nice_pct system_pct iowait_pct steal_pct idle_pct'),
        "mem":      ('-r',    'time ampm memfree_kb memused_kb memused_pct buffers_kb cached_kb commit_kb commit_pct active_kb inactive_kb'),
        "swap":     ('-S',    'time ampm swapfree_kb swapused_kb swapused_pct swapcad_kb swapcad_pct'),
        "all_io":   ('-b',    'time ampm ts read_ts write_ts read_bs write_bs'),
        "each_io":  ('-p -d', 'time ampm dev ts read_ss write_ss avg_req_sz avg_queue_sz avg_wait'),
        "switch":   ('-w',    'time ampm proc_s switch_s'),
        "queue":    ('-q',    'runq_sz plist_sz avg_load_1 avg_load_5 avg_load_15 blocked')
    }
    if mode in modes:
        options, columns = modes[mode]
        data = call_sar(options.split(), columns.split())
        if fmt is None:
            # return raw data (list of dict)
            return list(data)
        else:
            # return formatted data (list of str)
            return [fmt.format(**d) for d in data]
    else:
        raise ValueError("I don't know mode '{}'".format(mode))

现在您可以轻松地定义您的函数,如下所示:

def single_list():
    today = datetime.datetime.now().date()
    fmt   = "{} {} {} {}".format(today, '{time}', '{ampm}', '{memused_pct}')
    return get_system_stats("mem", fmt)

注意:我是在 Windows 7 机器上编写的,所以我没有 sar 并且无法实际运行测试它 - 它没有语法错误,我认为它应该可以正常工作,但它可能需要微调。

于 2012-09-19T02:41:02.627 回答
0
  • 你还没有time在你的fields函数中定义。好吧,(time,ampm,field1,field2,field3,field4,field5,field6,field7)该函数中没有定义...
  • 你不使用nfin singlelist,除了重新分配它。你想达到什么目的?
  • 您可以修改fields以接受参数(time,ampm,field1,field2,field3,field4,field5,field6,field7)中的method参数,但是您将如何定义它们?您仍然需要fieldssinglelist.
于 2012-09-18T15:29:34.033 回答