resueltos - ¿Cómo verifico si una función de python cambió(en código en vivo)?
llamar funciones dentro de funciones python (2)
Puede comparar los atributos del código de method.__code__.co_code
en el objeto de código usando el method.__code__.co_code
. Por ejemplo, vamos a definir dos clases:
>>> class A:
... a = 1
... def b(self, b):
... print(self.a + b)
...
>>> class B:
... a = 1
... def b(self, b):
... print(self.a + b)
...
>>> A().b.__code__.co_code
''|/x00/x00j/x00/x00|/x01/x00/x17GHd/x00/x00S''
>>> B().b.__code__.co_code
''|/x00/x00j/x00/x00|/x01/x00/x17GHd/x00/x00S''
>>> A().b.__code__.co_code == B().b.__code__.co_code
True
y si se cambia el método b
en la clase A
:
>>> class A:
... a = 1
... def b(self, b):
... print(b + self.a)
...
>>> A().b.__code__.co_code
''|/x01/x00|/x00/x00j/x00/x00/x17GHd/x00/x00S''
>>> A().b.__code__.co_code == B().b.__code__.co_code
False
o utilice el método inspect.getsource(object)
que:
Devuelve el texto del código fuente de un objeto. El argumento puede ser un módulo, clase, método, función, rastreo, marco u objeto de código. El código fuente se devuelve como una sola cadena.
Y si desea saber si el código ha cambiado en la dinámica, es posible que deba volver a cargar su clase con importlib
y comparar el código de importlib
.
Si tengo una referencia a una función, puedo verificar si es el código objeto f.__code__
, obtener una firma, y luego realizar comprobaciones posteriores contra esta firma para ver si el código cambió. Esto es bueno. Pero ¿y si una de las dependencias de la función cambia? P.ej
def foo(a, b):
return bar(a, b)
Digamos que foo
mantuvo igual, pero bar
cambió. ¿Hay alguna manera de verificar las dependencias de foo
''en vivo'' a través del objeto foo.__code__
(en lugar de analizar el texto y usar AST)?
Sólo estoy hurgando en el objeto __code__
aquí, así que no puedo decir que esto funcionaría con seguridad, pero me parece que podría usar la tupla de co_names
para (recursivamente) atravesar el gráfico de llamadas enraizado en una función particular , con el fin de crear algún tipo de hash del cierre transitivo de las funciones que podrían ser llamadas. (No creo que sea posible incluir solo las funciones a las que se llamará para una entrada en particular, pero podría ser conservador e incluir todas las llamadas posibles).
Para hacer esto, deberías mantener algún tipo de tabla de símbolos para poder buscar los nombres de las funciones a las que se llama. Pero una vez que empiezas por este camino, parece que básicamente vas a construir tu propio equivalente al AST. Entonces, ¿por qué no usar AST para comenzar?