Python Tkinter、asksaveasfile和unicode

Python Tkinter、asksaveasfile和unicode,python,python-3.x,unicode,tkinter,Python,Python 3.x,Unicode,Tkinter,长话短说,我正在制作一个程序,将一大堆Unicode写入一个文件。它通过使用Tkinterasksaveasfile对话框让用户选择要保存它的位置来实现这一点。这是一个令人不快的片段(顺便说一下,我将tkinter.filedialog导入为fudder只是为了好玩): 我看了几个像这样的问题,但没有一个特别提到这一点。asksaveasfile对话框的工作原理与open函数类似,但我无法指定编码。我尝试将其编码为字节,但您只能将字符串写入文件,无法将字节转换为字符串,然后再将其转换回字节。假设

长话短说,我正在制作一个程序,将一大堆Unicode写入一个文件。它通过使用Tkinter
asksaveasfile
对话框让用户选择要保存它的位置来实现这一点。这是一个令人不快的片段(顺便说一下,我将
tkinter.filedialog
导入为
fudder
只是为了好玩):


我看了几个像这样的问题,但没有一个特别提到这一点。
asksaveasfile
对话框的工作原理与
open
函数类似,但我无法指定编码。我尝试将其编码为字节,但您只能将字符串写入文件,无法将字节转换为字符串,然后再将其转换回字节。

假设您使用的是Python 3(
tkinter.filedialog
强烈建议您这样做),文件将以
locale.getpreferredencoding()
返回的区域设置编码打开。如果已经是UTF-8,那么您应该能够直接写入文件,而无需显式编码字符串

但是,由于您正在加密文件,
crypt()
可能会返回
字节
字符串,而不是
str
(unicode)字符串。如果是这种情况,则应以二进制模式打开输入和输出文件。然后在写入输出文件时不需要编码

name = fudder.askopenfilename(defaultextension =("Python Files","*.py"),title = "Choose a file to encrypt.")
with open(name, 'rb') as Usefile:
    filecont = Usefile.read()
    if filecont is None:
        return
    else:
        result = crypt(filecont)
        if result is None:
            return
        with fudder.asksaveasfile(mode = 'wb', defaultextension = '.txt', title = 'Save the decrypted file.') as newf:
            newf.write(result[0])
            newf.write(b'\n\n\nKey:\n\n\n')
            newf.write(result[1])
主要区别在于:

  • 文件以二进制模式打开
  • 无编码
  • 如果
    crypt()
    返回
    None

我检查了
asksaveasfile
的代码,实际上它只传递文件名和打开模式。严格来说,它是一个方便的函数,将调用
asksaveasfilename
与调用
open(filename,mode)
结合在一起,所有其他参数都是默认值。所以不要使用它

相反,使用
asksaveasfilename
并自己显式打开文件,就像对源文件所做的那样。然后,您可以使用
encoding='utf-8'
和任何其他非默认选项编写所需的开放呼叫


带有的第一个
应该在您阅读了
Usefile
之后结束,并且不再需要它。因此,应该删除
if
语句。

Python 2或Python 3?我使用的是Python 3.5
if filecont为None
是假的。
read()。这就是方法。我正在寻找一种用Asksaveasfile和编码保存熊猫数据帧的方法。我想这个答案对我会有很大帮助:)谢谢
name = fudder.askopenfilename(defaultextension =("Python Files","*.py"),title = "Choose a file to encrypt.")
with open(name, 'rb') as Usefile:
    filecont = Usefile.read()
    if filecont is None:
        return
    else:
        result = crypt(filecont)
        if result is None:
            return
        with fudder.asksaveasfile(mode = 'wb', defaultextension = '.txt', title = 'Save the decrypted file.') as newf:
            newf.write(result[0])
            newf.write(b'\n\n\nKey:\n\n\n')
            newf.write(result[1])