¿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.Python - ¿Cómo escribo un decorador que restaura el cwd?
Respuesta
El módulo path.py (que realmente debería usar si se trata de caminos en los scripts de Python) tiene un gestor de contexto:
subdir = d/'subdir' #subdir is a path object, in the path.py module
with subdir:
# here current dir is subdir
#not anymore
(créditos van a this blog post de Rob erto Alsina)
Si path.py ahora está incorporado, quizás debería responder http://stackoverflow.com/questions/3899761/will-the-real-path-py-please-stand-up. –
desafortunadamente no lo es, pero gracias. No estaba al tanto de la pregunta – CharlesB
. Creo que malinterpreté su respuesta. ¿Quiso decir que el administrador de contexto está integrado en path.py? (Pensé que querías decir que path.py ahora está integrado en Python.) –
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
Necesita manejo de errores, ver mi respuesta. – codeape
La respuesta para un decorador se le ha dado; 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 que en la función llamada etapa usando un gestor 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 utilizar si es necesario en el momento llamada a 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.
EDITAR: He añadido 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.
* Y * se puede utilizar para escribir el decorador antes mencionado :) – Constantin
Necesita manejo de errores, ver mi respuesta. – codeape
¿El manejo de errores necesita un try/finally explícito? Pensé que el punto de los administradores de contexto era que siempre se llamaba MANAGER .__ exit__. Pero entonces, nunca he probado el decorador desde contextlib, así que no sé cuáles son los problemas. –
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 gestor de contexto:
@contextlib.contextmanager
def remember_cwd():
curdir = os.getcwd()
try:
yield
finally:
os.chdir(curdir)
- 1. ¿Cómo escribirías un decorador @debuggable en python?
- 2. decorador en Python currying
- 3. instancia de python que restablece el método de memoial decorador
- 4. Registro de Python usando un decorador
- 5. El decorador de Python con multiprocesamiento falla
- 6. Implementando el patrón de decorador en Python
- 7. Python: Decorador de excepciones. Cómo conservar stacktrace
- 8. PHP equivalente para un decorador de python?
- 9. ¿Cómo uso una ruta relativa en un módulo de Python cuando la CWD ha cambiado?
- 10. ¿Cómo creo un decorador de memorando delimitado en Python?
- 11. clases de decorador en Python
- 12. Decorador para sobrecargar en Python
- 13. cómo hacer un decorador condicional en python 2.6
- 14. ¿Cómo escribo correctamente en FIFOs en Python?
- 15. Python novato @patch tema decorador
- 16. ¿Cómo escribo una "pestaña" en Python?
- 17. ¿Cómo escribo un filtro de Unix en Python?
- 18. Escribir un decorador de clase que se aplica un decorador a todos los métodos
- 19. EditText no restaura el estado en DialogFragment
- 20. ¿Cómo crear un decorador de Python que se pueda usar con o sin parámetros?
- 21. ¿Cómo escribo un dialecto externo para SQLAlchemy?
- 22. ¿Cómo escribo un representante para PyYAML?
- 23. ¿Cómo el sistema de control de revisión restaura la revisión?
- 24. ¿Cómo escribo un género peor que O (n!)
- 25. Python Decorator 3.0 y argumentos para el decorador
- 26. ¿Cómo escribo un complemento jQuery que se llama como `$ .myplugin.func()`?
- 27. python: decorar una clase definiendo el decorador como una clase
- 28. Decorar un decorador
- 29. ¿Existe un decorador memoize en disco para python?
- 30. extrañeza con un decorador
Y usted hizo la pregunta y la respondió usted mismo en 3 minutos porque ...? Obviamente tuviste la respuesta (que difícilmente se puede mejorar) incluso antes de hacer la pregunta. Realmente me gustaría saber tu razonamiento. – tzot
Preguntas frecuentes dice "También es perfectamente correcto preguntar y responder a su propia pregunta de programación". Enumera tres criterios requeridos para las preguntas, y "usted no sabe la respuesta" no es uno de ellos. –
Escribí el código y luego resultó (después de la refactorización) que no lo necesitaba. Pensé que stackoverflow es un buen lugar para archivarlo, y quizás otros puedan beneficiarse. –