Mi chiedo se sia possibile creare un metodo che si comporta in modo diverso quando viene chiamato come metodo di classe rispetto a quando viene chiamato come metodo di istanza.Un metodo di classe che si comporta diversamente quando viene chiamato come metodo di istanza?
Ad esempio, come progetto di miglioramento delle capacità, sto scrivendo una classe Matrix
(sì, so che ci sono classi matrix perfettamente buone già disponibili). Ho creato un metodo di classe per questo chiamato identity
che restituisce una matrice di identità di una dimensione specificata.
Ora, quando viene richiamata l'istanza di Matrix
, sembra logico che la dimensione non debba essere specificata; dovrebbe restituire una matrice di identità della stessa dimensione di Matrix
chiamata.
In altre parole, mi piacerebbe definire un metodo che può determinare se è stato chiamato tramite un'istanza e, in tal caso, accedere agli attributi di quell'istanza. Sfortunatamente, anche dopo aver esplorato la documentazione e alcune ricerche su Google, non ho trovato nulla che suggerisca che ciò sia possibile. Qualcuno lo sa diversamente?
Edit:
Wow! Chiaramente, non sono ancora abbastanza abituato alle funzioni di prima classe. Ecco cosa ho ottenuto - grazie a Unknown per aver fornito la chiave!
class Foo(object):
def __init__(self, bar):
self.baz = bar
self.bar = MethodType(lambda self: self.__class__.bar(self.baz), self, self.__class__)
@classmethod
def bar(cls, baz):
return 5 * baz
Foo.bar(3) # returns 15
foo = Foo(7)
foo.bar() # returns 35
Edit 2:
Solo una breve nota - questa tecnica (e la maggior parte di quelli presentati qui di seguito) non funziona su classi che definiscono __slots__
, in quanto non è possibile riassegnare il metodo.
La domanda richiedeva un singolo oggetto chiamabile che potesse rilevare come veniva chiamato. (Questo dovrebbe essere possibile usando il modulo inspect per ottenere il frame di chiamata.) La 'soluzione' presentata è quella di creare un secondo callable, un metodo associato, che è associato a ogni istanza con lo stesso nome del primo callable. Questo potrebbe risolvere il problema di come avere classi e "metodi di istanza" con lo stesso nome. Ma non è la stessa cosa di avere un solo callable che può agire come entrambi. –
@TerryJanReedy è possibile ispezionare il frame di chiamata in fase di esecuzione? – aayush
Sì, questo è ciò che intendevo con "usa il modulo inspect per ottenere il frame di chiamata". Ci sono una o più funzioni per questo. –