resueltos programacion poo otra orientada objetos metodo llamar lista instancia importar ejercicios constructores clases clase python stack runtime sequence-diagram

programacion - poo python 3



¿Cómo obtener el nombre de la clase que llama dentro de una función de otra clase en python? (5)

Bueno, después de un poco de excavación en el indicador, esto es lo que obtengo:

stack = inspect.stack() the_class = stack[1][0].f_locals["self"].__class__ the_method = stack[1][0].f_code.co_name print("I was called by {}.{}()".format(str(calling_class), calling_code_name)) # => I was called by A.a()

Cuando se invoca:

➤ python test.py A.a() B.b() I was called by __main__.A.a()

dado el archivo test.py :

import inspect class A: def a(self): print("A.a()") B().b() class B: def b(self): print("B.b()") stack = inspect.stack() the_class = stack[1][0].f_locals["self"].__class__ the_method = stack[1][0].f_code.co_name print(" I was called by {}.{}()".format(str(the_class), the_method)) A().a()

No estoy seguro de cómo se comportará cuando se le llame desde algo que no sea un objeto.

Mi objetivo es estimular un diagrama de secuencia de una aplicación para esto. Necesito la información sobre los nombres de las clases de la persona que llama y la persona que llama en el tiempo de ejecución. ¿Puedo recuperar con éxito la función de la persona que llama pero no puedo obtener un nombre de clase de la persona que llama?

#Scenario caller.py: import inspect class A: def Apple(self): print "Hello" b=B() b.Bad() class B: def Bad(self): print"dude" print inspect.stack() a=A() a.Apple()

Cuando imprimí la pila no había información acerca de la clase que llamaba. Entonces, ¿es posible recuperar la clase que llama durante el tiempo de ejecución?


En lugar de indexar el valor de retorno de inspect.stack (), se podría usar el método inspect.currentframe (), que evita la indexación.

prev_frame = inspect.currentframe().f_back the_class = prev_frame.f_locals["self"].__class__ the_method = prev_frame.f_code.co_name


Para almacenar el nombre de instancia de clase de la pila a la variable de clase:

import inspect class myClass(): caller = "" def __init__(self): s = str(inspect.stack()[1][4]).split()[0][2:] self.caller = s def getInstanceName(self): return self.caller

Esta

myClassInstance1 = myClass() print(myClassInstance1.getInstanceName())

imprimirá:

myClassInstance1


Quizás esto está rompiendo algún protocolo de programación de Python, pero si Bad siempre va a verificar la clase de la persona que llama, ¿por qué no pasarle la __class__ la persona que llama como parte de la llamada?

class A: def Apple(self): print "Hello" b=B() b.Bad(self.__class__) class B: def Bad(self, cls): print "dude" print "Calling class:", cls a=A() a.Apple()

Resultado:

Hello dude Calling class: __main__.A

Si esta es una forma incorrecta, y usar la función de inspect verdaderamente es la forma preferida de obtener la clase de la persona que llama, explique por qué. Todavía estoy aprendiendo sobre conceptos más profundos de Python.


Usando la respuesta de Python: ¿Cómo recuperar información de clase de un objeto ''marco''?

Me sale algo como esto ...

import inspect def get_class_from_frame(fr): args, _, _, value_dict = inspect.getargvalues(fr) # we check the first parameter for the frame function is # named ''self'' if len(args) and args[0] == ''self'': # in that case, ''self'' will be referenced in value_dict instance = value_dict.get(''self'', None) if instance: # return its class return getattr(instance, ''__class__'', None) # return None otherwise return None class A(object): def Apple(self): print "Hello" b=B() b.Bad() class B(object): def Bad(self): print"dude" frame = inspect.stack()[1][0] print get_class_from_frame(frame) a=A() a.Apple()

Lo que me da la siguiente salida:

Hello dude <class ''__main__.A''>

claramente esto devuelve una referencia a la clase en sí. Si desea el nombre de la clase, puede obtenerlo del atributo __name__ .

Desafortunadamente, esto no funcionará para la clase o métodos estáticos ...