qué patron parametros ejemplo decoradores decorador con python decorator cwd

patron - qué es un decorador en python



Python: ¿cómo escribo un decorador que restaura el cwd? (4)

¿Cómo escribo un decorador que restaura el directorio de trabajo actual a lo que era antes de llamar a la función decorada? En otras palabras, si uso el decorador en una función que hace un os.chdir (), el cwd no se cambiará después de que se llame a la función.


def preserve_cwd(function): def decorator(*args, **kwargs): cwd = os.getcwd() result = function(*args, **kwargs) os.chdir(cwd) return result return decorator

Así es como se usa:

@preserve_cwd def test(): print ''was:'',os.getcwd() os.chdir(''/'') print ''now:'',os.getcwd() >>> print os.getcwd() /Users/dspitzer >>> test() was: /Users/dspitzer now: / >>> print os.getcwd() /Users/dspitzer


La respuesta para un decorador ha sido dada; funciona en la etapa de definición de la función según lo solicitado.

Con Python 2.5+, también tiene una opción para hacer eso en la etapa de llamada de función usando un administrador de contexto:

from __future__ import with_statement # needed for 2.5 ≤ Python < 2.6 import contextlib, os @contextlib.contextmanager def remember_cwd(): curdir= os.getcwd() try: yield finally: os.chdir(curdir)

que se puede usar si es necesario en el tiempo de llamada de la función como:

print "getcwd before:", os.getcwd() with remember_cwd(): walk_around_the_filesystem() print "getcwd after:", os.getcwd()

Es una buena opción para tener.

EDITAR: Agregué el manejo de errores como lo sugiere codeape. Dado que mi respuesta ha sido votado, es justo ofrecer una respuesta completa, dejando de lado todas las demás cuestiones.


Las respuestas dadas no tienen en cuenta que la función envuelta puede generar una excepción. En ese caso, el directorio nunca será restaurado. El siguiente código agrega manejo de excepciones a las respuestas anteriores.

como decorador:

def preserve_cwd(function): @functools.wraps(function) def decorator(*args, **kwargs): cwd = os.getcwd() try: return function(*args, **kwargs) finally: os.chdir(cwd) return decorator

y como administrador de contexto:

@contextlib.contextmanager def remember_cwd(): curdir = os.getcwd() try: yield finally: os.chdir(curdir)


El módulo path.py (que realmente debe usar si se trata de rutas en scripts de Python) tiene un administrador de contexto:

subdir = d / ''subdir'' #subdir is a path object, in the path.py module with subdir: # here current dir is subdir #not anymore

(los créditos van a esta publicación del blog de Roberto Alsina)