Python 3: Catching warnings during multiprocessing

后端 未结 3 1141
醉话见心
醉话见心 2021-01-03 19:54

Too long; didn\'t read

The warnings.catch_warnings() context manager is not thread safe. How do I use it in a parallel processing environment?

Background<

3条回答
  •  -上瘾入骨i
    2021-01-03 20:20

    you can try to override the Process.run method to use warnings.catch_warnings.

    >>> from multiprocessing import Process
    >>> 
    >>> def yell(text):
    ...    import warnings
    ...    print 'about to yell %s' % text
    ...    warnings.warn(text)
    ... 
    >>> class CustomProcess(Process):
    ...    def run(self, *args, **kwargs):
    ...       import warnings
    ...       with warnings.catch_warnings():
    ...          warnings.simplefilter("ignore")
    ...          return Process.run(self, *args, **kwargs)
    ... 
    >>> if __name__ == '__main__':
    ...    quiet = CustomProcess(target=yell, args=('...not!',))
    ...    quiet.start()
    ...    quiet.join()
    ...    noisy = Process(target=yell, args=('AAAAAAaaa!',))
    ...    noisy.start()
    ...    noisy.join()
    ... 
    about to yell ...not!
    about to yell AAAAAAaaa!
    __main__:4: UserWarning: AAAAAAaaa!
    >>> 
    

    or you can use some of the internals... (__warningregistry__)

    >>> from multiprocessing import Process
    >>> import exceptions
    >>> def yell(text):
    ...    import warnings
    ...    print 'about to yell %s' % text
    ...    warnings.warn(text)
    ...    # not filtered
    ...    warnings.warn('complimentary second warning.')
    ... 
    >>> WARNING_TEXT = 'AAAAaaaaa!'
    >>> WARNING_TYPE = exceptions.UserWarning
    >>> WARNING_LINE = 4
    >>> 
    >>> class SelectiveProcess(Process):
    ...    def run(self, *args, **kwargs):
    ...       registry = globals().setdefault('__warningregistry__', {})
    ...       registry[(WARNING_TEXT, WARNING_TYPE, WARNING_LINE)] = True
    ...       return Process.run(self, *args, **kwargs)
    ... 
    >>> if __name__ == '__main__':
    ...    p = SelectiveProcess(target=yell, args=(WARNING_TEXT,))
    ...    p.start()
    ...    p.join()
    ... 
    about to yell AAAAaaaaa!
    __main__:6: UserWarning: complimentary second warning.
    >>> 
    

提交回复
热议问题