在python中读取多个依赖文件

2024-09-28 19:07:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用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]

问题是,第一行似乎没有移到下一行。它一遍又一遍地打印出同一行。portslistconstantfile以及使用constantfile=open("constantfile.dat").readlines()等在程序中声明的else where列表。我对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

我知道我不应该用操作系统,但这应该是一个又快又脏的工作小项目。该计划是为了保持跟踪大量的打印机(数千)在线状态在很长一段时间(年)。它通过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\u last\u checked last\u online\u date time\u in\u 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

下面是一些在for line in portslist:之后带有print (line)的输出

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

Tags: inforifaddressdefcounterfilewrite
2条回答

读取文件的所有行时,必须使用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

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

  • 为变量命名:
    • for port_info in portlines:
    • for printer_details in consntantfile:
  • 用下划线分隔变量名中的单词:
    • printer_name,而不是printername。你知道吗
    • old_utc,而不是old_utc。你知道吗
  • 不要依赖于portlinesconstantfile这样的全局变量,而是将它们作为参数传递给这个函数。然后您就可以用一小部分数据调用这个函数,并手工调试问题。你知道吗
  • 为我们提供了两个文件的内容,以及您的程序输出。你知道吗

相关问题 更多 >