¿Cómo se comprueba si un método de Python está vinculado o no?
-
09-06-2019 - |
Pregunta
Dada una referencia a un método, ¿hay alguna forma de comprobar si el método está vinculado a un objeto o no?¿También puedes acceder a la instancia a la que está vinculado?
Solución
def isbound(method):
return method.im_self is not None
def instance(bounded_method):
return bounded_method.im_self
Métodos definidos por el usuario:
Cuando se crea un objeto de método definido por el usuario recuperando un objeto de función definido por el usuario de una clase, su
im_self
atributo esNone
y se dice que el objeto del método está desaconsejado.Cuando uno se crea recuperando un objeto de función definido por el usuario de una clase a través de una de sus instancias, suim_self
El atributo es la instancia, y se dice que el objeto del método está obligado.En cualquier caso, el nuevo métodoim_class
El atributo es la clase de la que tiene lugar la recuperación y suim_func
El atributo es el objeto de función original.
En pitón 2.6 y 3.0:
Los objetos del método de instancia tienen nuevos atributos para el objeto y la función que comprende el método;el nuevo sinónimo de
im_self
es__self__
, yim_func
también está disponible como__func__
.Los viejos nombres todavía son compatibles con Python 2.6, pero se han ido en 3.0.
Otros consejos
En Python 3 el __self__
atributo es solo establecido en métodos enlazados.No está configurado para None
en funciones simples (o métodos independientes, que son simplemente funciones simples en Python 3).
Utilice algo como esto:
def is_bound(m):
return hasattr(m, '__self__')
La respuesta elegida es válida en casi todos los casos.Sin embargo, al verificar si un método está vinculado a un decorador usando la respuesta elegida, la verificación fallará.Considere este decorador y método de ejemplo:
def my_decorator(*decorator_args, **decorator_kwargs):
def decorate(f):
print(hasattr(f, '__self__'))
@wraps(f)
def wrap(*args, **kwargs):
return f(*args, **kwargs)
return wrap
return decorate
class test_class(object):
@my_decorator()
def test_method(self, *some_params):
pass
El print
La declaración en el decorador se imprimirá. False
.En este caso no puedo encontrar otra manera que verificar los parámetros de la función usando sus nombres de argumentos y buscar uno llamado self
.Esto es también no Se garantiza que funcionará perfectamente porque el primer argumento de un método no está obligado a ser nombrado. self
y puede tener cualquier otro nombre.
import inspect
def is_bounded(function):
params = inspect.signature(function).parameters
return params.get('self', None) is not None
soy uno mismo atributo (sólo Python 2)