python print 函数出错

最近在进行多模态视频语义理解,环境配置anaconda3,python版本3.7.4,win10 系统,运行完一段代码后,发现print内置函数总是出错,出错内容如下:

D:\Anaconda3\lib\codecs.py in write(self, object)
    376         """
    377         data, consumed = self.encode(object, self.errors)
--> 378         self.stream.write(data)
    379 
    380     def writelines(self, list):

D:\Anaconda3\Lib\site-packages\ipykernel\iostream.py in write(self, string)
    512         if not isinstance(string, str):
    513             raise TypeError(
--> 514                 f"write() argument must be str, not {type(string)}"
    515             )
    516 

TypeError: write() argument must be str, not 

查看print函数的源代码,未找到,不过个人认为调用的顺序如下:

print()->stream.write()

print内置函数的help 文档(即help(print))如下:
Help on built-in function print in module builtins:
print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream.

从上述文档中可以看出,print默认输出至sys.stdout,即标准输出,不过也可以输出至文件。而python 3.7.13的print内置函数官方文档如下:

print(*objectssep=' 'end='\n'file=sys.stdoutflush=False)

Print objects to the text stream file, separated by sep and followed by endsependfile and flush, if present, must be given as keyword arguments.

All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.

The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Since printed arguments are converted to text strings, print() cannot be used with binary mode file objects. For these, use file.write(...) instead.

Whether output is buffered is usually determined by file, but if the flush keyword argument is true, the stream is forcibly flushed.

Changed in version 3.3: Added the flush keyword argument.

发现出错的语句中有下面一句:

sys.stdout = codecs.getwriter("utf-8")(sys.stdout),

上述语句为强制类型转换,把sys.stdout的属性给修改了,修改前,print(sys.stdout)为:

ipykernel.iostream.OutStream object at 0x000001B5440914C8,

使用下面语句,进行临时输出(因为实际修改后则无法输出)

stdout_temp = codecs.getwriter("utf-8")(sys.stdout)
print(stdout_temp)

临时输出修改后的对象为:

encodings.utf_8.StreamWriter object at 0x000001B5451C6F08,

从上面可以看出两者不是同一个类,更不是同一个对象,导致write的参数出错,最终出现上面的错误。将上述语句sys.stdout = codecs.getwriter("utf-8")(sys.stdout),注释起来,然后重启jupyter内核,发现一切正常,所以系统变量不可轻易修改。

参考资料:

1Built-in Functions — Python 3.7.13 documentationhttps://docs.python.org/3.7/library/functions.html#print

 

你可能感兴趣的:(机器学习,python,开发语言)