¿Puedo definir una función que, cuando se invoca, inserta locales nuevos en el alcance de la persona que llama? Tengo la sensación de que la aprobación de locales del llamante() en la función que podría funcionar, pero ¿hay una manera de hacer lo que quiera sin tener que hacer esto?¿Inyectar variables en el alcance de la persona que llama?
Respuesta
Por reglas de Python, no se puede alterar de locals
su interlocutor; en las implementaciones actuales, si se intenta (por ejemplo, con la magia negro Anurag sugiere) no obtendrá una excepción (aunque me gustaría añadir que el registro de error a alguna versión futura), pero será esencialmente inoperante si la persona que llama es una función (no si la persona que llama es el código de nivel superior del módulo): las variables locales reales de la persona que llama no se verán afectadas de hecho. Esto es válido si se pasan de forma explícita de la persona que llama en locals
, o descabellada través de la magia negro: que todavía tienen que ser tratados como un solo lectura dict si el código ha de tener alguna cordura.
Más bien, podría hacer que la persona que llama pase un dict explícito, real, normal (que se puede inicializar desde locals()
si lo desea), y todas las alteraciones que haga su código en esa frase estarán allí para su uso. - pero no tan "nuevos" en barenames ámbito local de la persona que llama, por supuesto, pero la funcionalidad es la misma tanto si la persona que llama tiene que utilizar x['foo']
o x.foo
o (como se prefiere) justo barename foo
.
Por cierto, para usar la sintaxis de atributo de acceso en lugar de la sintaxis de indexación dict, que puede hacer:
class Bunch(object): pass
...
# caller code
b = Bunch()
thefun(b)
print b.foo
...
# called function
def thefun(b):
b.foo = 23
Esto también cubre, con una pequeña variación, el caso en el que thefun
quiere trabajar con la sintaxis de indexación dict (digamos que su cuerpo es b['foo'] = 23
en lugar de b.foo = 23
): en ese caso, la persona que llama solo necesita usar thefun(vars(b))
en lugar del thefun(b)
normal, pero luego puede seguir trabajando con la sintaxis de acceso b.foo
.
Bueno, parece que no es posible hacer lo que quiero. Gracias por la idea de acceso al atributo; si no puedo tener nombres desnudos (x), la siguiente cosa más bonita es probablemente el acceso a los atributos (context.x). – jogloran
Esto no es cierto, consulte la respuesta a continuación utilizando el módulo de inspección incorporado de python para ver cómo se hace. Python es un lenguaje dinámico completo que puede sobrescribir su propio intérprete si así lo desea. Solo cito http://xkcd.com/353/ – Pykler
Alex es correcto. La respuesta de @ Pykler solo funciona en un caso específico, y no en general. – ferrouswheel
Mira la inspect module, que es utilizado por minimock burlarse alcance de la persona que llama.
Este código debe hacer exactamente lo que quiere:
import inspect
def mess_with_caller():
stack = inspect.stack()
try:
locals_ = stack[1][0].f_locals
finally:
del stack
locals_['my_new_function'] = lambda : 'yaaaaaay'
mess_with_caller()
print my_new_function()
>>> Output: 'yaaaaaay'
Esto no es posible sin cambiar la API, como CPython conserva una referencia a la lista de argumentos para la duración de la llamada de función.
Una forma de hacer esto es pasar un objeto y desactive el estado interno del objeto cuando se hace uso de ella.
class Obj(object):
def __init__(self, state):
self.state = state
def f(o):
# Do stuff with o.state
del o.state
- 1. ¿Cómo puedo lanzar una excepción desde el alcance de la persona que llama?
- 2. Obtener el módulo de la persona que llama en Ruby
- 3. SignalR Obtener la dirección IP de la persona que llama
- 4. Burlándose: ¿cómo hago una excepción en la persona que llama?
- 5. Obtener el alcance de la función que llama
- 6. ¿No se puede determinar la identidad de la aplicación de la persona que llama?
- 7. Reemplazando "nuevo" y registrando datos sobre la persona que llama
- 8. ¿Por qué la persona que llama debe borrar la pila en la convención de llamadas cdecl?
- 9. Python: cómo obtener el nombre del método de la persona que llama en el método llamado?
- 10. regreso de una persona que llama lambda C++ 0x directamente
- 11. Obtener el nombre de host de la persona que llama en WCF
- 12. Atajo de Xcode para ir a la siguiente "persona que llama" en el Asistente de edición?
- 13. ¿Es posible obtener el contexto de la persona que llama en javascript?
- 14. Obtener traza la función en bash desde el manejador de trampa (usando persona que llama)
- 15. Alcance de variables en KSH
- 16. ¿Se puede evaluar el código en el contexto de una persona que llama en Ruby?
- 17. ¿Cómo utilizar inspeccionar para obtener la información de la persona que llama de callee en Python?
- 18. Error de WCF: la persona que llama no fue autenticada por el servicio
- 19. cambiar el número de la persona que llama durante una llamada entrante
- 20. ¿Cómo obtengo la dirección IP de la persona que llama en un WebMethod?
- 21. ¿Debería la función o la persona que llama ser responsable de la validación de entrada?
- 22. Cómo determinar el número de teléfono de una persona que llama actualmente en una aplicación independiente
- 23. ¿Puedo predeterminar un argumento de función al valor de __FILE__ en la persona que llama?
- 24. En Android, ¿cómo encuentro la persona que llama de un método de manera eficiente
- 25. Moose :: Error :: Informe de errores Croak no desde la perspectiva de la persona que llama
- 26. ¿Cómo `` gethostbyname` volver hostent struct * `sin requerir la persona que llama para liberar el recurso?
- 27. ¿Es posible colocar un controlador de eventos en un hilo diferente para la persona que llama?
- 28. En Perl, ¿debería funcionar una función la danza wantarray, o podemos esperar que la persona que llama use el mapa?
- 29. Sub para crear un objeto de tipo pasado por la persona que llama en VB.NET
- 30. Devolver un objeto opaco a la persona que llama sin violar la seguridad de tipo
Supongamos que se espera que la persona que llama comprenda los riesgos de que el destinatario acuda a la ciudad con sus locales. – jogloran
Suena como una receta para espaguetis –
Se llama "devolución". –