Il tuo amico ha torto. I metodi sono attributi.
Tutto in Python è oggetti, in realtà, con metodi e funzioni e qualsiasi cosa con un metodo __call__()
come oggetti callable . Sono tutti oggetti che rispondono alla sintassi delle espressioni di chiamata ()
.
Quindi gli attributi sono oggetti trovati dalla ricerca di attributi su altri oggetti. Non importa al meccanismo di ricerca degli attributi che ciò che viene cercato è un oggetto chiamabile o meno.
Puoi osservare questo comportamento cercando il solo e non chiamandolo:
>>> class Foo(object):
... def bar(self):
... pass
...
>>> f = Foo()
>>> f.bar
<bound method Foo.bar of <__main__.Foo object at 0x1023f5590>>
Qui f.bar
è un'espressione di ricerca di attributi, il risultato è un oggetto metodo.
Certo, anche il tuo amico mi sta un po 'bene; ciò che sta realmente accadendo è che i metodi sono oggetti speciali che racchiudono funzioni , mantenendo i riferimenti all'istanza sottostante e alla funzione originale, e vengono creati al volo accedendo alla funzione come attributo. Ma questo potrebbe complicare un po 'le cose quando inizi a cercare di capire gli oggetti Python. Se sei interessato a come funziona, leggi il Python Descrittore HOWTO per vedere come attributi con metodi speciali sono trattati in modo diverso su determinati tipi di accesso agli attributi.
Tutto funziona perché Python è un linguaggio dinamico; non sono richieste dichiarazioni di tipo. Per quanto riguarda la lingua, non importa se Foo.bar
è una stringa, un dizionario, un generatore o un metodo. Ciò è in contrasto con i linguaggi compilati, in cui i dati sono molto diversi dai metodi e ogni campo di un'istanza deve essere preventivamente annidato a un tipo specifico. I metodi generalmente sono oggetti non , quindi un concetto separato dai dati.