Python - temporarily modify the current process's environment

前端 未结 6 1822
清歌不尽
清歌不尽 2020-11-30 05:47

I use the following code to temporarily modify environment variables.

@contextmanager
def _setenv(**mapping):
    \"\"\"``with`` context to temporarily modi         


        
6条回答
  •  一个人的身影
    2020-11-30 06:04

    I suggest you the following implementation:

    import contextlib
    import os
    
    
    @contextlib.contextmanager
    def set_env(**environ):
        """
        Temporarily set the process environment variables.
    
        >>> with set_env(PLUGINS_DIR=u'test/plugins'):
        ...   "PLUGINS_DIR" in os.environ
        True
    
        >>> "PLUGINS_DIR" in os.environ
        False
    
        :type environ: dict[str, unicode]
        :param environ: Environment variables to set
        """
        old_environ = dict(os.environ)
        os.environ.update(environ)
        try:
            yield
        finally:
            os.environ.clear()
            os.environ.update(old_environ)
    

    EDIT: more advanced implementation

    The context manager below can be used to add/remove/update your environment variables:

    import contextlib
    import os
    
    
    @contextlib.contextmanager
    def modified_environ(*remove, **update):
        """
        Temporarily updates the ``os.environ`` dictionary in-place.
    
        The ``os.environ`` dictionary is updated in-place so that the modification
        is sure to work in all situations.
    
        :param remove: Environment variables to remove.
        :param update: Dictionary of environment variables and values to add/update.
        """
        env = os.environ
        update = update or {}
        remove = remove or []
    
        # List of environment variables being updated or removed.
        stomped = (set(update.keys()) | set(remove)) & set(env.keys())
        # Environment variables and values to restore on exit.
        update_after = {k: env[k] for k in stomped}
        # Environment variables and values to remove on exit.
        remove_after = frozenset(k for k in update if k not in env)
    
        try:
            env.update(update)
            [env.pop(k, None) for k in remove]
            yield
        finally:
            env.update(update_after)
            [env.pop(k) for k in remove_after]
    

    Usage examples:

    >>> with modified_environ('HOME', LD_LIBRARY_PATH='/my/path/to/lib'):
    ...     home = os.environ.get('HOME')
    ...     path = os.environ.get("LD_LIBRARY_PATH")
    >>> home is None
    True
    >>> path
    '/my/path/to/lib'
    
    >>> home = os.environ.get('HOME')
    >>> path = os.environ.get("LD_LIBRARY_PATH")
    >>> home is None
    False
    >>> path is None
    True
    

    EDIT2

    A demonstration of this context manager is available on GitHub.

提交回复
热议问题