在python中读取多个依赖文件

时间:2012-08-31 17:01:32

标签: python file for-loop

我正在使用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一个从打印服务器拉出的打印机列表,并在constantfile中记录日期,在线状态和端口名称来完成此操作。

这是portslist文件中的一行: 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' 格式为“name port date_last_checked last_online_date time_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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

让您的代码更易于阅读和测试,然后您会发现问题更容易。 Speficically:

  • 为他们持有的内容命名变量:
    • for port_info in portlines:
    • for printer_details in consntantfile:
  • 使用下划线分隔变量名称中的单词:
    • printer_name,而不是printername
    • old_utc,而不是old_utc
  • 不要依赖portlinesconstantfile之类的全局变量,而是将它们作为参数传递给此函数。然后,您将能够使用一小组数据调用此函数,并手动调试问题。
  • 为我们提供了两个文件的内容以及程序的输出。