0

我正在用python编写一个程序并且遇到了一些麻烦。我的程序应该做的是从文件中读取一行,解析它,然后将该行的一部分写入字符串。然后它应该在另一个文件中搜索该字符串,并在找到时打印该行。然后它应该向下移动到第一个文件的下一行并重复该过程,直到第一个文件中的所有行都被读取。

我的代码如下:

def readermain():
    """called if constant file exists"""

    for line in portslist: #reads printer port list and parses name and port address 
        marker = line.split()
        printername=marker[0]
        address=marker[1]

        for lines in constantfile:
            if address in lines: #if the desired address is in the line
                lineholder=lines.split()
                print (lineholder)
                oldonline=lineholder[4]
                oldutc=lineholder[5]
                status=lineholder[2]
                address=lineholder[1]

问题是,第一个for line in portslist似乎没有移动到下一行。它一遍又一遍地打印出同一行。和portslistconstantfile列表在程序中使用constantfile=open("constantfile.dat").readlines()等声明的其他位置。我是 python 新手,似乎无法弄清楚这里发生了什么。任何帮助或建议都非常受欢迎。

程序本身很长,我累了总结问题区域,但我会在下面发布。这是一项正在进行的工作,所以我知道还有其他错误,是的,这不是可读性的最佳示例,sry。建议还是很棒的。

"""Program to pull down list of printers and ping each to see if it is online. 
Will track printers over time, if printer has been offline for over a year it will be listed in a delete file.
This program is designed to run on windows and requires python to be installed. """

import win32com.client, os, time, datetime
from datetime import datetime




computername="(name goes here)"
currentdate=datetime.now()
currentdateutc= (time.mktime(currentdate.timetuple()))

def getPorts(computername):
    """Gets printer name and port name"""

    portslist= open("printerports.txt","w")

    objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
    objSWbemServices = objWMIService.ConnectServer(computername,"root\cimv2") 
    colItems = objSWbemServices.ExecQuery("Select * from Win32_Printer") 
    for objItem in colItems:
        list= objItem.Name + " " + objItem.PortName+"\n"
        portslist.write(list)

    portslist.close()

def pingone(address):
    """Pings address and returns 0 if it is online"""
    pingreturn=os.system("ping -n 1 " + address)
    return (pingreturn)

def pingfive(address):
    """Pings as address five times"""
    pingreturn=os.system("ping -n 5 " + address)
    return (pingreturn)

def online(printername, address, currentdate):
    return str((printername +" at port "+ address+" is online on "+ str(currentdate)+"\n"))

def offline(printername, address, currentdate):
    return str((printername +" at port "+address+" is offline on "+ str(currentdate)+"\n"))

def constantonline(printername, address, currentdate, currentdateutc):
    return str((printername+" "+address+" "+str(0)+" "+str(currentdate)+" "+str(currentdate)+" "+str(currentdateutc)+"\n"))

def constantoffline(printername, address, currentdate, oldonline, oldutc):
    return str((printername+" "+address+" "+str(1)+" "+str(currentdate)+" "+str(oldonline)+" "+str(oldutc)+"\n"))

def removal(printername, address, oldonline):
    return str((printername+" with queue "+address+" has been offline since "+str(oldonline)+"\n"))

def constantfilecheck():
    """Checks for constant file"""
    if os.path.isfile("constantfile.dat")==True:  #checks if a constant file exists. if not one is made
        return True

    else:
        return False

def readermain(portslist, constantfile, counter, oncounter, offcounter):
    """called if constant file exists"""

    for line in portslist: #reads printer port list and parses name and port address 
        print(line)
        marker = line.split()
        printername=marker[0]
        address=marker[1]

        for lines in constantfile:
            print(lines)
            if address in lines: #if the desired address is in the line
                lineholder=lines.split()
                print (lineholder)
                oldonline=lineholder[4]
                oldutc=lineholder[5]
                status=lineholder[2]
                address=lineholder[1]
                #--------------------------------------------------------------------------------------------------------------------------------------------
                print ("Address found in constant file")

                if pingone(address)==0:
                    newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                    onlinefile.write(online(printername, address, currentdate))
                    oncounter += 1
                    counter += 1

                else:
                    if pingfive(address)==0:
                        newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                        onlinefile.write(online(printername, address, currentdate))
                        oncounter += 1
                        counter += 1

                    else:
                        newconstantfile.write(constantoffline(printername, address, currentdate, oldonline, oldutc))
                        offlinefile.write(offline(printername, address, currentdate))
                        offcounter += 1
                        counter += 1
                        if status == 0 and (currentdateutc-oldutc)>=31556926:
                            #-----------------------------------------------------------------------------------------------------------------------------------
                            print("printer older than year")
                            deletefile=open("removefile.txt", "a")
                            deletefile.write(removal(printername, address, oldonline))
                            deletefile.close()
            else:
                #not in constant file
                #------------------------------------------------------------------------------------------------------------------------------------------------
                print("not in constant file")
                if pingone(address)==0:
                    newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                    onlinefile.write(online(printername, address, currentdate))
                    oncounter += 1
                    counter += 1

                else:
                    if pingfive(address)==0:
                        newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                        onlinefile.write(online(printername, address, currrentdate))
                        oncounter += 1
                        counter += 1

                    else:
                        newconstantfile.write(printername+" "+address+" "+str(1)+" "+str(currentdate)+" "+str(oldonline)+" "+str(currentdateutc)+"\n")
                        offlinefile.write(offline(printername, address, currentdate))
                        offcounter += 1
                        counter += 1

def readersecondary(oncounter, offcounter, counter):
    """called if no constant file exists already"""

    for line in portslist: #reads printer port list and parses name and port address 

        marker = line.split()
        printername=marker[0]
        address=marker[1]

        if pingone(address)==0:
            newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
            onlinefile.write(online(printername, address, currentdate))
            oncounter += 1
            counter += 1

        else:
            if pingfive(address)==0:
                newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                onlinefile.write(online(printername, address, currrentdate))
                oncounter += 1
                counter += 1

            else:
                newconstantfile.write(printername+" "+address+" "+str(1)+" "+str(currentdate)+" "+str(currentdate)+" "+str(currentdateutc)+"\n")
                offlinefile.write(offline(printername, address, currentdate))
                offcounter += 1
                counter += 1
    return counter, oncounter, offcounter
def rename():
    """Deleates old constant file and renames newconstantfile to constantfile"""
    if constantfilecheck() is True:
        os.system("del constantfile.dat")

    os.system("ren newconstantfile.dat constantfile.dat")
    os.system("del printerports.txt")

#_______________________________________________________________________________________________________________
#END OF FUNCTIONS
#_______________________________________________________________________________________________________________


oncounter=0
offcounter=0
counter=0

print ("Getting ports from server\n")   
getPorts(computername)

portslist=open("printerports.txt", "r").readlines()
newconstantfile=open("newconstantfile.dat", "w")
onlinefile=open("onlinefile.txt", "w")
offlinefile=open("offlinefile.txt", "w")

print ("checking for constant file")
if constantfilecheck() == True:
    constantfile=open("constantfile.dat").readlines()
    print("calling reader main")
    readermain(portslist, constantfile, counter, oncounter, offcounter)
    constantfile.close()
elif constantfilecheck() == False:
    print("calling reader secondary")
    readersecondary(oncounter, offcounter, counter)

offlinefile.write("\nTotal Printers Scanned: "+str(counter))
offlinefile.write("\nPrinters online: "+str(oncounter))
offlinefile.write("\nPrinters offline: "+str(offcounter))
onlinefile.write("\nTotal Printers Scanned: "+str(counter))
onlinefile.write("\nPrinters online: "+str(oncounter))
onlinefile.write("\nPrinters offline: "+str(offcounter))

portslist.close()
newconstantfile.close()
onlinefile.close()
offlinefile.close()

rename() #calls rename function

我知道我不应该使用 os.system,但这应该是一个快速而肮脏的小项目。该程序旨在在很长一段时间(数年)内跟踪大量打印机(数以千计)的在线状态。它通过 ping 从打印服务器中提取的打印机列表并在常量文件中记录日期、在线状态和端口名称来实现这一点。

下面是 portslist 文件中的一行: artp002 10.40.80.18formatted "name port"

这是常量文件的示例:`artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0' 格式为“名称端口日期_上次检查的最后在线日期时间_in_utc

这是程序运行时的输出:

Getting ports from server

checking for constant file
calling reader main
artp002 10.40.80.18

artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=6ms TTL=61

Ping statistics for 10.40.80.18:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 6ms, Maximum = 6ms, Average = 6ms
artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=6ms TTL=61

Ping statistics for 10.40.80.18:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 6ms, Maximum = 6ms, Average = 6ms
artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=6ms TTL=61

这是print (line)后面的一些输出for line in portslist:

Getting ports from server

checking for constant file
calling reader main
artp002 10.40.80.18

artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=8ms TTL=61

Ping statistics for 10.40.80.18:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 8ms, Maximum = 8ms, Average = 8ms
artp011 artp011.printers.xxxxxx.edu 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

not in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=8ms TTL=61
4

2 回答 2

0

让你的代码更容易阅读和测试,然后你会更容易发现问题。具体来说:

  • 为它们所持有的变量命名:
    • for port_info in portlines:
    • for printer_details in consntantfile:
  • 用下划线分隔变量名中的单词:
    • printer_name,不是printername
    • old_utc,不是old_utc
  • 不要依赖像portlinesand这样的全局变量constantfile,而是将它们作为参数传递给这个函数。然后,您将能够使用一小组数据调用此函数,并手动调试问题。
  • 向我们提供了两个文件的内容,以及您的程序的输出。
于 2012-08-31T17:22:09.203 回答
0

当您读取文件的所有行时,您必须使用 . 将光标回退到开头file_object.seek(0)。否则,进一步尝试读取行返回None。我在下面更正了您的代码,请参见最后一行:

def readermain():
    """called if constant file exists"""

    for line in portslist: #reads printer port list and parses name and port address 
        marker = line.split()
        printername=marker[0]
        address=marker[1]

        for lines in constantfile:
            if address in lines: #if the desired address is in the line
                lineholder=lines.split()
                print (lineholder)
                oldonline=lineholder[4]
                oldutc=lineholder[5]
                status=lineholder[2]
                address=lineholder[1]

        constantfile.seek(0) # rewinds the file
于 2012-08-31T17:04:51.927 回答