我收到了可以完全忽略的特定警告。该警告可能最终会被修补,并且我的目标是从控制台中删除该警告(以使其杂乱无章,减少我不得不查看的垃圾邮件)。
具体地说,我尝试在macOS Mojave上的Python3软件包FolderBrowse()
中使用PySimpleGUI
。这会在运行时显示以下消息:
objc[2542]: Class FIFinderSyncExtensionHost is implemented in both /System/Library/PrivateFrameworks/FinderKit.framework/Versions/A/FinderKit (0x7fff9408e3d8) and /System/Library/PrivateFrameworks/FileProvider.framework/OverrideBundles/FinderSyncCollaborationFileProviderOverride.bundle/Contents/MacOS/FinderSyncCollaborationFileProviderOverride (0x1073e4f50). One of the two will be used. Which one is undefined.
再次,我的目的是忽略以上警告,而不是自己修复。
我还看到了其他python警告抑制问题,例如this one
但是,我并不是要隐藏一组警告(例如:DeprecationWarning
)。相反,我只想隐藏上面显示的一个警告。
编辑,我正在使用的代码:
import PySimpleGUI as sg
window_rows = [[sg.InputText(), sg.FolderBrowse()]]
sg.Window('', window_rows).Read()
答案 0 :(得分:0)
我对PySimpleGUI
不熟悉,因此我不知道如何在Python中使该警告静音。通过简单地忽略警告中的特定文本,可以考虑使警告“静默”:
python myfile.py 2> >(grep -v 'FIFinderSyncExtensionHost' 1>&2)
这当然假定您正在从终端运行Python。另外,如果警告使用的是stdout
而不是stderr
,则您必须使用
python myfile.py | grep -v 'FIFinderSyncExtensionHost'
相反。
答案 1 :(得分:0)
在带有OP提供的链接的页面上,描述了一种将禁止显示单个警告消息的技术。
不幸的是,我无法在Windows或Linux机器上重复您的警告,因此我无法确定此修复程序是否有效,但是可以:
import warnings
warnings.filterwarnings('ignore', message='Class FIFinderSyncExtensionHost is implemented in both')
该代码显然将根据消息中的部分文本进行过滤。还有其他可用选项,例如使用模块名称等。
此解决方案的优点在于,有太多方法可以获取应忽略的指标。在上面的示例中,我处理了部分错误消息,并将其用于对filterwarnings
的调用中。它使您可以轻松过滤单个警告消息或一组警告消息。
这里有一个演示程序,既可以生成警告,也可以演示如何使用文本来过滤它。
import PySimpleGUI as sg
import warnings
layout = [[sg.Text('My Text Editor')],
[sg.B('Enable Filter'), sg.B('Warning')],]
window = sg.Window('My Text Editor', layout)
while True: # Event Loop
event, values = window.Read()
if event is None:
break
print(event, values)
if event == 'Warning':
warnings.warn("my warning goes here")
elif event.startswith('Enable'):
warnings.filterwarnings('ignore', message='my warning')
window.Close()
Python文档在此处描述了警告模块: https://docs.python.org/3.6/library/warnings.html#warnings.filterwarnings
并且此页很好地解释了一些概念: https://pymotw.com/2/warnings/
由于上述方法1无法解决问题,因此您可以在显示令人反感的消息时重新路由stderr和/或stdout。
这是一个小的测试程序,它将重新路由并还原stderr和stdout并将其重新设置为正常。使用它可以关闭一个或另一个,并在重新引出一个文件时尝试执行FileBrowse。这至少会告诉您它是在stdout,stderr还是在这两者上显示。
import PySimpleGUI as sg
import sys
sg.ChangeLookAndFeel('GreenTan')
layout = [ [sg.In(), sg.FileBrowse()],
[sg.OK(), sg.B('StdErr Reroute'), sg.B('StdOut Reroute'), sg.B('Restore')]]
window = sg.Window('My new window', layout)
temp_stderr = temp_stdout = None
while True: # Event Loop
event, values = window.Read()
if event is None:
break
elif event.startswith('StdErr'):
temp_stderr = sys.stderr
sys.stderr = None
elif event.startswith('StdOut'):
temp_stdout = sys.stdout
sys.stdout = None
elif event == 'Restore':
if temp_stderr:
sys.stderr = temp_stderr
temp_stderr = None
if temp_stdout:
sys.stdout = temp_stdout
temp_stdout = None
print(event, values)
运行此命令时,在重新路由标准输出后按OK(确定)按钮,您将看不到控制台上的任何内容。再次还原它,然后单击“确定”,您将再次看到输出。
如果您能够通过重新路由到任何地方然后再次进行还原而仅包围引起问题的大量代码,则此技术应该可以工作。
如果您不能临时重新路由,则可以创建一个将stdout和stderr重新路由到您的类的类。这将为您提供完全的过滤控制,以便在显示警告时,您不允许这些字符出现在官方的stdout / stderr中,而对于其他所有内容,您都将通过这些数据。
答案 2 :(得分:0)
请参阅以下文档的Temporarily Suppressing Warnings节
warnings
模块:
如果您使用的代码知道会发出警告(例如已弃用的函数),但又不想看到该警告(即使已通过命令行明确配置了警告),则可以禁止显示使用catch_warnings上下文管理器发出警告:
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fxn()
在上下文管理器中,所有警告都将被忽略。这使您可以使用已知已弃用的代码,而不必查看警告,而不必为可能不知道其已弃用代码的其他代码取消警告。 (...)
这似乎正是您所需要的,不是吗?
答案 3 :(得分:0)
我发现类似这样的东西可以解决此错误:
copied_stderr = 0
try:
if is_mac:
# Redirect stderr to /dev/null to hide annoying FIFinderSyncExtensionHost warning
copied_stderr = os.dup(2)
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, 2)
os.close(devnull)
result = func(**args)
finally:
if copied_stderr > 0:
os.dup2(copied_stderr, 2)
os.close(copied_stderr)
如果您多次遇到此问题,可以创建一个执行重定向的contextmanager。