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

3

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

在我的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()

我还尝试将打印url移动到加入列表之后,但没有成功,我也尝试使用print "",但仍然出现了前面提到的错误。

所以我想我已经找到了一个解决方案...但有人能解释一下这种行为吗?我是做错了什么吗?(你需要我发帖整个脚本让你可以研究它吗?)

编辑:这是整个代码:

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(),尽管我已经在发布的代码中添加了print url,这似乎使其在90%的情况下可以正常运行,而没有它则100%出现错误。

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

friend1
friend2
friend3

对我来说,即使没有 QueryESO.xml 文件(当然如果没有错误的话),它似乎也可以很好地创建 QueryESO.xml。 如果您的情况不是这样,请使用名为 QueryESO.xml 的空文件,因为它会从网页获取其内容。

“刷新”按钮中存在错误。


4
file 是 Python 内置文件类型的名称;覆盖它被视为不良习惯。 - Katriel
我发布的代码就是我的脚本中的内容...所以前面没有任何路径或目录。这能够工作是因为文件在同一个目录下(对吧?)。还有@katrielalex: 我会确保将其从覆盖内置文件名更改。 - user631175
我会为你发布我的所有代码。此外,我正在使用2.7.1版本。 - user631175
1
我怀疑这并不相关,但是在 DeleteFriend() 函数中的 if name in fs 部分缺少一个 f.close() - Matt Gibson
当我在Windows上使用Ipython时遇到这个问题,我只需转义路径中的所有反斜杠("C:\Foo\bar" 变成 "C:\Foo\Bar"),这样就解决了我的问题。 - justin cress
显示剩余2条评论
2个回答

3

一些观察结果:

(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) 我不是一个放弃谜题的人,但是:你从网络中获取结果,在两个地方将其写入此文件中并读取回来——为什么?为什么不直接在内存中使用网络结果呢?


1
我真的不确定我为什么这样做。我没有一个合法的理由。我只是试图让它工作。有时候我就是想不到这些事情;这只是我写的第三个或者第四个正式程序,所以我还是个新手。我会尝试从内存中读取结果。 - user631175
我正在做同样的事情,原因是我上传一个文件进行调整大小,然后再将其上传到亚马逊S3。我遇到了相同的错误。 http://stackoverflow.com/questions/17467967/invalid-filename-or-mode-wb - Sohaib
我遇到了同样的问题,也出现了“90%的时间正常工作”的情况。我正在将命令行的输出记录到文件中。我已经创建了几个文件来记录不同命令的输出。我猜这可能是问题发生的原因。 - Wei Yang

0

由于'w'是一个有效的模式,问题出在文件名上。也许您在某个上下文中没有使用相同的系统编码。如果只在一个函数中出现问题,可能是该文件名实例中存在一些隐藏字符。解决这个问题的第一步是将文件名设置为模块级常量。


我将文件名更改为常量,但它仍然在一个模块中无法工作,而在其他模块中仍然可以工作。仅仅通过打印列表和URL就能解决问题,这让我感到困惑。 - user631175
@user 嗯,要么是因为它引入了延迟,要么是因为它导致了某种I/O缓冲刷新或类似的东西,我猜测是这样。如果你用sleep(1)代替打印会发生什么?(首先要import time...) - Matt Gibson
@Matt 好吧...我现在尝试使用sleep,但是当我添加sleep(1)时,它给出错误,NameError:全局名称'sleep'未定义,我还尝试了time.sleep(1),它告诉我:UnboundLocalError:本地变量'time'在赋值之前被引用。我确实导入了time...当在另一个文件中使用import time和time.sleep(1)时,它工作正常...我不确定我做错了什么? - user631175

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接