繁体   English   中英

莫名其妙的ResourceWarning:未关闭的文件<_io.TextIOWrapper名称= 3

[英]Inexplicable ResourceWarning: unclosed file <_io.TextIOWrapper name=3

我正在完成将代码从python2.7移至python3.5的操作,并打开warnings以检查另一个模块。
使用os.popen()时,出现以下错误。

ResourceWarning: unclosed file <_io.TextIOWrapper name=3 encoding='UTF-8'>

上面的示例中的“ name = 3”中的数字将有所变化,具体取决于代码,但是它始终是整数。
此代码段产生错误,但尚未打开任何文件,这与错误消息unclosed file完全冲突。
我的环境是使用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)

结果如下:

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

有谁知道为什么发出此警告,尤其是在这种情况下,没有打开文件?

整数是文件描述符 ,操作系统用来谈论分配给进程的文件句柄的整数。 012stdinstdoutstderr ,3个和至多是用于进一步文件描述符。

之所以收到资源警告,是因为您打开了文件句柄,但从未明确关闭它。 相反,您只需要在Python文件对象包装器上调用.readlines().readline()

sink_list = os.popen('pacmd list-sinks | grep "name:" | cut --delimiter=: -f2').readlines()

这使文件对象被垃圾收集器关闭,您将收到警告。 您可以使用打开的对象作为上下文管理器来为您关闭它:

 with os.popen('pacmd list-sinks | grep "name:" | cut --delimiter=: -f2') as list_sinks:
    sink_list = list_sinks.readlines()

就个人而言,我将使用subprocess模块来处理外部流程,并使用Python进行行选择。 这样可以避免启动单独的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM