Python - 无效模式('w')或文件名

4 投票
2 回答
29585 浏览
提问于 2025-04-16 12:29

我遇到了一个很奇怪的错误。

在我的Python脚本中,有一段代码是很多函数的一部分:

url=['http://API_URL/query/query.aspx?name=', name, '&md=user']
url=''.join(url)
file = open("QueryESO.xml", "w")
filehandle = urllib.urlopen(url)
for lines in filehandle.readlines():
    file.write(lines)
file.close()

当我在IDLE里运行时,一切都很好。

但是如果我在命令行用Python运行,就会出现这个错误:

[Errno 22] invalid mode('w') or filename: 'QueryESO.xml'

事情开始变得奇怪了:

奇怪 #1:我在脚本的不同函数里有完全相同的代码,但这个错误只在其中一个函数里出现。

奇怪 #2:如果我把代码改成这样,它就能正常工作:

url=['http://API_URL/query/query.aspx?name=', name, '&md=user']
print url
url=''.join(url)
file = open("QueryESO.xml", "w")
filehandle = urllib.urlopen(url)
for lines in filehandle.readlines():
    file.write(lines)
file.close()

我还尝试把打印网址的代码移到我把列表合并之后,这也不行。我还试过打印一个空字符串,这也出现了之前提到的错误。

所以我想我找到了一个解决办法……但有人能解释一下这种情况吗?我是不是做错了什么?(你需要我把整个脚本发出来让你看看吗?)

编辑:这是整个代码:

import urllib
from Tkinter import *
import tkFont
master = Tk()

QUERY_ESO = "QueryESO.xml"

def QueryXML(xml, attribute):
    x = ["<", attribute, ">"]
    x=''.join(x)
    z = xml.split(x, 1)
    x = ["</", attribute, ">"]
    x=''.join(x)
    z=z[1]
    z=z.split(x, 1)
    return z[0]

def AddFriend():
    nfentry = nfe2
    name=nfentry.get()
    url=['http://agecommunity.com/query/query.aspx?name=', name, '&md=user']
    url=''.join(url)
    file = open("QueryESO.xml", "w")
    filehandle = urllib.urlopen(url)
    for lines in filehandle.readlines():
        file.write(lines)
    file.close()
    f = open(QUERY_ESO, "r")
    xml = f.readlines()
    f.close()
    xml=''.join(xml)
    f = open("Friends.txt", "r")
    filestring = f.read()
    f.close()
    fs = filestring.split('\n')
    if name in fs:
        print "Friend Already Added"
    elif xml == "<?xml version='1.0' encoding='utf-8'?><error>Failed to find user</error>":
        print "User does not exist"
    else:
        fs.append(name)
        fs = '\n'.join(fs)
        f = open("Friends.txt", "w")
        f.write(fs)
        f.close()
    nfe2.set("")
    nfentry = nfe2

def DeleteFriend():
    ofentry = ofe2
    name=ofentry.get()
    f = open("Friends.txt", "r")
    filestring = f.read()
    f.close()
    fs = filestring.split('\n')
    if name in fs:
        fs.remove(name)
        fs = '\n'.join(fs)
        f = open("Friends.txt", "w")
        f.write(fs)
    ofe2.set("")
    ofentry = ofe2
    
def IsOnline(name):
    url=['http://API_URL/query/query.aspx?name=', name, '&md=user']
    print url
    url=''.join(url)
    file = open("QueryESO.xml", "w")
    filehandle = urllib.urlopen(url)
    for lines in filehandle.readlines():
        file.write(lines)
    file.close()
    f = open(QUERY_ESO, "r")
    xml = f.readlines()
    f.close()
    xml=''.join(xml)
    if xml == "<?xml version='1.0' encoding='utf-8'?><error>Failed to find user</error>":
        print "User does not exist"
    else: 
        datetime = QueryXML(xml, "LastUpdated")
        datetime = datetime.split('T', 1)
        time = datetime[1].split('Z', 1)
        date = datetime[0]
        print "User", name, "is", QueryXML(xml, "presence"), "as of", date, "at", time[0]
        return QueryXML(xml, "presence")

def FriendCheck():
    f = open("Friends.txt", "r")
    filestring = f.read()
    f.close()
    fs = filestring.split('\n')
    Laonline = Label(lowerframe, text="")
    Laonline.grid(column=0, row=0)
    Laonline.grid_forget()
    x=0
    while x <= (len(fs)-1):
        if IsOnline(fs[x]) == "online":
            Laonline = Label(lowerframe, text=fs[x])
            Laonline.grid(column=0, row=x)
        x=x+1

def RunTwo(Function1, Function2):
    Function1()
    Function2()

def DeleteAllFriends():
    fs = "<?xml version='1.0' encoding='utf-8'?>\n<friends>\n</friends>"
    f = open("Friends.txt", "w")
    f.write(fs)
    f.close()
    FriendCheck()

def DAFPop():
    DAFpopup = Toplevel()
    DAFframe = Frame(DAFpopup)
    DAFframe.grid(columnspan=4, column=0, row=0)
    F1 = DeleteAllFriends
    F2 = DAFpopup.destroy
    Q1 = lambda: RunTwo(F1, F2)
    DAFL1 = Label(DAFframe, text="This delete all of your friends. Are you sure you wish to continue?")
    DAFL1.grid()
    DAFOK = Button(DAFpopup, width=10, text="Yes", command=Q1)
    DAFOK.grid(column=1, row=1)
    DAFNO = Button(DAFpopup, width=10, text="No", command=DAFpopup.destroy)
    DAFNO.grid(column=2, row=1)

frame = Frame(master, bd=5)
frame.grid()

friendlist = Frame(frame, bd=5, width=150, height=400)
friendlist.grid(column=0, row=0, rowspan=15)

lon = Frame(friendlist, bd=2, width=150, height=10)
lon.grid()

Lonline = Label(lon, text="Friends Online")
Lonline.grid(column=0, row=1)
underlined = tkFont.Font(Lonline, Lonline.cget("font"))
underlined.configure(underline=True)
Lonline.configure(font=underlined)

lowerframe = Frame(friendlist, bd=2, width=150, height=390)
lowerframe.grid()

lowerframe.grid_propagate(0)

newfriendframe = Frame(frame, bd=2)
newfriendframe.grid(column=1, row=0)

nfe2 = StringVar()
nfentry = Entry(newfriendframe, width=12, textvariable=nfe2)
nfentry.grid()
nfe2.set("")
nfentry = nfe2.get()

newfriend = Button(newfriendframe, text="Add Friend", width=10, command=AddFriend)
newfriend.grid(column=0, row=1)

oldfriendframe = Frame(frame, bd=2)
oldfriendframe.grid(column=1, row=1)

ofe2 = StringVar()
ofentry = Entry(oldfriendframe, width=12,textvariable=ofe2)
ofentry.grid()
ofe2.set("")
ofentry = ofe2.get()

oldfriend = Button(oldfriendframe, text="Delete Friend", width=10, command=DeleteFriend)
oldfriend.grid(column=0, row=1)

rof = Button(frame, text="Reset List", width=10, command=DAFPop)
rof.grid(column=1, row=2)

update = Button(frame, text="Refresh", width=10, command=FriendCheck)
update.grid(column=1, row=3)

close = Button(frame, text="Exit", width=10, command=master.destroy)
close.grid(column=1, row=4)

master.mainloop()

而且出问题的函数是IsOnline(),虽然我在我发的代码里保留了打印网址的部分,这样它在90%的情况下能正常运行,而没有它时100%都会出错。

它还依赖一个文本文件,叫Friends.txt:

friend1
friend2
friend3

即使QueryESO.xml文件不存在,它似乎也能正常创建这个文件(当然是当没有错误的时候)。如果你那边不行,创建一个空的QueryESO.xml文件也可以,因为它的内容是从网页获取的。

出错的地方在“刷新”按钮的代码里。

2 个回答

0

因为'w'是一个有效的模式,所以问题出在文件名上。可能你在某个地方没有使用相同的系统编码。如果这个问题只出现在一个函数里,文件名中可能有一些隐藏的字符。解决这个问题的第一步是把文件名定义成一个模块级的常量。

4

一些观察:

(1) 如果问题是文件名中有无效字符,错误信息会很明显地显示出来;见下文:

>>> open('fu\x01bar', 'w')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] invalid mode ('w') or filename: 'fu\x01bar'

(2) 你说你在使用一个全局常量作为文件名,但在两个地方(在AddFriend和IsOnline函数中)出现了文字的重复使用——确保你发布的代码和你实际运行的代码一致,这样会更有帮助。

(3) 这种“90%时间都能正常工作”的情况有一个原因,就是某个扩展(比如tkinter)没有处理异常,导致在其他地方检查错误时才会出现问题。注意,对于错误号22,Windows只会报告“发生了某种错误”,而Python则会提示“哦,那可能是模式不对,或者文件路径不对”的错误信息。

(4) 我不是那种轻易放弃的人,但在两个地方你从网上获取结果,写入这个文件,然后再读取回来——为什么呢?为什么不直接在内存中使用网络结果呢?

撰写回答