TL;DR
INDEX = 0
#: change to new file location
logger.handlers[INDEX].setStream( open('/path/to/new/log/file.log', 'a') )
#: change to stdout or stderr
import sys
logger.handlers[INDEX].setStream( sys.stdout ) # or sys.stderr
#: change to another device
logger.handlers[INDEX].setStream( open('/dev/ttys010', 'a') )
- after registering a logging.FileHandlerto your logger, you can reach into its internals and change the stream it outputs to "on the fly".
- make sure INDEXaccesses the right handler within the logger. if you only added aFileHandler, then it should be index0.
Explained
Well first, following the logging documentation's suggested idiom, you would get a new logger instance named after the __name__ of whatever your specific package, module, class, or function:
#: class
>>> class A:
        def __init__(self):
            self.logger = logging.getLogger(self.__class__.__name__)
>>>A().logger
<Logger A (WARNING)>
#: function
>>> def func():
        logger = logging.getLogger(func.__name__)
        print(logger)
>>> func()
<Logger func (WARNING)>
#: module
>>> logger = logging.getLogger( __name__ )
>>> logger
<Logger __main__ (WARNING)>
#: package (e.g. a package named 'pkg', write this in '__init__.py')
>>> logger = logging.getLogger( __package__ )
>>> logger
<RootLogger pkg (WARNING)>
Next, if you've registered a logging.FileHandler handler for your logger, like so:
logger.addHandler( logging.FileHandler('/tmp/logfile.log', 'a') )
then you can you can change the file it outputs to by replacing the stream it outputs to:
INDEX = 0  # you will have to find the index position of the `FileHandler` you 
           # registered to this logger. I justed listed them with: `logger.handlers`
           # and picked the one I needed. if you only register one handler
           # then it should be at index 0, i.e the first one
#: change to new file location
logger.handlers[INDEX].setStream( open('/path/to/new/log/file.log', 'a') )
#: change to stdout or stderr
import sys
logger.handlers[INDEX].setStream( sys.stdout ) # or sys.stderr
#: change to another device
logger.handlers[INDEX].setStream( open('/dev/ttys010', 'a') )
If your curious, found this in a few minutes, by doing a bit of digging like so (in ipython and python interpreters):
>>> import logging
>>> logger = logging.getLogger( __name__ )
>>> logger.addHandler( logging.FileHandler('/tmp/logfile', 'a') )
>>> globals()
>>> dir(logger)
#: found that the logger has 'handlers' attribute
>>> dir(logger.handlers)
>>> logger.handlers
#: found that the FileHandler I registered earlier is at index: 0
>>> logger.handlers[0]
>>> dir(logger.handlers[0])
#: found that FileHandler has a dictionary '__dict__'
>>> logger.handlers[0].__dict__
#: found that FileHandler dict has 'baseFilename' attribute with the filename
#: i had set when registering the file handler
>>> logger.handlers[0].__dict__['baseFilename']
#: tried changing the file it points to
>>> logger.handlers[0].__dict__['baseFilename'] = '/tmp/logfile.log'
#: tried logging
>>> logger.info(f'hello world')
#: didn't work
#: found another interesting perhaps relevant attribute 'stream' in the
#: FileHandler dict
>>> logger.handlers[0].__dict__['stream']
>>> dir(logger.handlers[0].__dict__['stream'])
>>> logger.handlers[0].__dict__['stream'].__dict__
#: tried replacing the stream altogether
>>> logger.handlers[0].__dict__['stream'] = open('/tmp/logfile.log','a')
#: tried logging
>>> logger.info(f'hello world again')
#: it worked
>>> logger.info(f'hey it worked')
#: found another interesting perhaps relevant method 'setStream'
>>> logger.handlers[0].setStream( open('/tmp/otherlogfile.log','a') )
#: tried logging
>>> logger.info(f'hello world again')
#: it worked
>>> logger.info(f'hey it worked')