[英]Inexplicable ResourceWarning: unclosed file <_io.TextIOWrapper name=3
I am finalising moving my code from python2.7 to python3.5 and turned on warnings
to check another module. 我正在完成将代码从python2.7移至python3.5的操作,并打开
warnings
以检查另一个模块。
When using os.popen()
I am getting the following error. 使用
os.popen()
时,出现以下错误。
ResourceWarning: unclosed file <_io.TextIOWrapper name=3 encoding='UTF-8'>
The number in the above example "name=3" will change, depending on the code but it is always a integer. 上面的示例中的“ name = 3”中的数字将有所变化,具体取决于代码,但是它始终是整数。
This code snippet produces the error and yet no file has been opened, which is in complete conflict with the error message unclosed file
. 此代码段产生错误,但尚未打开任何文件,这与错误消息
unclosed file
完全冲突。
My environment is Linux using python 3.5.2 我的环境是使用python 3.5.2的Linux
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import warnings
import os
warnings.simplefilter('default')
sink_list = os.popen('pacmd list-sinks | grep "name:" | cut --delimiter=: -f2').readlines()
print (sink_list)
sink = os.popen('pacmd list | grep "Default sink name" | cut --delimiter=: -f2').readline()
print(sink)
Results in the following: 结果如下:
test.py:6: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 encoding='UTF-8'>
sink_list = os.popen('pacmd list-sinks | grep "name:" | cut --delimiter=: -f2').readlines()
[' <alsa_output.pci-0000_00_1b.0.analog-stereo>\n', ' <fs2-Equaliser>\n', ' <fs2-bs2b>\n']
test.py:8: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 encoding='UTF-8'>
sink = os.popen('pacmd list | grep "Default sink name" | cut --delimiter=: -f2').readline()
fs2-Equaliser
Does anyone know why this warning is issued, especially in this circumstance, where no file has been opened? 有谁知道为什么发出此警告,尤其是在这种情况下,没有打开文件?
The integer is a file descriptor , the integer number the OS uses to talk about file handles assigned to a process. 整数是文件描述符 ,操作系统用来谈论分配给进程的文件句柄的整数。
0
, 1
and 2
are stdin
, stdout
and stderr
, 3 and up are further file descriptors used. 0
, 1
和2
是stdin
, stdout
和stderr
,3个和至多是用于进一步文件描述符。
You get the resource warning because you open the file handle, but never close it explicitly. 之所以收到资源警告,是因为您打开了文件句柄,但从未明确关闭它。 You instead just call
.readlines()
or .readline()
on the Python file object wrapper: 相反,您只需要在Python文件对象包装器上调用
.readlines()
或.readline()
:
sink_list = os.popen('pacmd list-sinks | grep "name:" | cut --delimiter=: -f2').readlines()
This leaves the file object to be closed by the garbage collector, and you get the warning. 这使文件对象被垃圾收集器关闭,您将收到警告。 You can use the open object as a context manager to have it closed for you:
您可以使用打开的对象作为上下文管理器来为您关闭它:
with os.popen('pacmd list-sinks | grep "name:" | cut --delimiter=: -f2') as list_sinks:
sink_list = list_sinks.readlines()
Personally, I'd use the subprocess
module to handle external processes, and use Python to do the line selection. 就个人而言,我将使用
subprocess
模块来处理外部流程,并使用Python进行行选择。 This lets you avoid spinning up a separate sh
process and generally has much nicer exception handling: 这样可以避免启动单独的
sh
进程,并且通常具有更好的异常处理:
import subprocess
# read list of sinks
result = suprocess.run(['pacmd', 'list-sinks'], stdout=subprocess.STDOUT, encoding='UTF-8')
sink_list = [l.split(':', 2) for l in result.stdout if 'name:' in l]
# read default sink
result = suprocess.run(['pacmd', 'list'], stdout=subprocess.STDOUT, encoding='UTF-8')
default_sink = next((l.split(':', 2) for l in result.stdout if 'Default sink name' in l), None)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.