Come si verifica se un metodo Python è associato o meno?
-
09-06-2019 - |
Domanda
Dato un riferimento a un metodo, esiste un modo per verificare se il metodo è associato o meno a un oggetto?Puoi accedere anche all'istanza a cui è associato?
Soluzione
def isbound(method):
return method.im_self is not None
def instance(bounded_method):
return bounded_method.im_self
Quando viene creato un oggetto metodo definito dall'utente recuperando un oggetto funzione definito dall'utente da una classe, è
im_self
l'attributo èNone
E si dice che l'oggetto metodo sia illimitato.Quando uno viene creato recuperando un oggetto di funzione definito dall'utente da una classe tramite una delle sue istanze, èim_self
L'attributo è l'istanza e si dice che l'oggetto metodo sia vincolato.In entrambi i casi, il nuovo metodoim_class
L'attributo è la classe da cui avviene il recupero e la suaim_func
L'attributo è l'oggetto funzione originale.
In Pitone 2.6 e 3.0:
Gli oggetti del metodo di istanza hanno nuovi attributi per l'oggetto e la funzione che comprendono il metodo;il nuovo sinonimo di
im_self
È__self__
, Eim_func
è disponibile anche come__func__
.I vecchi nomi sono ancora supportati in Python 2.6, ma sono spariti in 3.0.
Altri suggerimenti
In Python 3 il __self__
l'attributo è soltanto impostato su metodi vincolati.Non è impostato su None
su funzioni semplici (o metodi non associati, che sono semplicemente funzioni semplici in Python 3).
Usa qualcosa del genere:
def is_bound(m):
return hasattr(m, '__self__')
La risposta scelta è valida in quasi tutti i casi.Tuttavia, quando si verifica se un metodo è associato a un decoratore utilizzando la risposta scelta, il controllo fallirà.Considera questo decoratore e metodo di esempio:
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
IL print
verrà stampata l'istruzione nel decoratore False
.In questo caso non riesco a trovare altro modo se non quello di controllare i parametri della funzione usando i nomi degli argomenti e cercarne uno con nome self
.Questo è anche non garantito per funzionare perfettamente perché il primo argomento di un metodo non è obbligato a essere nominato self
e può avere qualsiasi altro nome.
import inspect
def is_bounded(function):
params = inspect.signature(function).parameters
return params.get('self', None) is not None
io_me stesso attributo (solo Python 2)