Poiché il proprietario può essere facilmente derivato dall'istanza, il secondo argomento è facoltativo. Solo quando non c'è un'istanza da cui derivare un proprietario, è necessario l'argomento proprietario.
Questo è descritto nella proposta che introduce descrittori, PEP 252 - Making Types Look More Like Classes:
__get__
: una funzione richiamabile con uno o due argomenti che recupera il valore di attributo da un oggetto. Questo è anche definito come operazione "vincolante", poiché può restituire un oggetto "metodo associato" nel caso dei descrittori di metodo. Il primo argomento , X
, è l'oggetto da cui deve essere recuperato l'attributo oa cui deve essere associato.Quando X è None
, il opzionale secondo argomento, T
, dovrebbe essere metaoggetto e operazione di legatura può restituire un metodo non legato limitato a istanze di T
.
(grassetto in grassetto).
Il binding, dal primo giorno, era pensato per essere applicabile all'istanza da solo, con il tipo facoltativo. Metodi non ne hanno bisogno, per esempio, in quanto possono essere legati al solo esempio:
>>> class Foo: pass
...
>>> def bar(self): return self
...
>>> foo = Foo()
>>> foo.bar = bar.__get__(foo) # look ma! no class!
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0x10a0c2710>>
>>> foo.bar()
<__main__.Foo object at 0x10a0c2710>
Inoltre, il secondo argomento può facilmente essere derivato dal primo argomento; assistere a un classmethod
ancora vincolante per la classe, anche se non abbiamo passato uno in:
>>> classmethod(bar).__get__(foo)
<bound method type.bar of <class '__main__.Foo'>>
>>> classmethod(bar).__get__(foo)()
<class '__main__.Foo'>
L'unica ragione per cui l'argomento è lì, in primo luogo è quello di sostenere vincolante in classe, per esempio quando non ci sono istanze da associare a. Il metodo di classe di nuovo; legame None
come istanza non funziona, funziona solo se abbiamo effettivamente passa nella classe:
>>> classmethod(bar).__get__(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __get__(None, None) is invalid
>>> classmethod(bar).__get__(None, Foo)
<bound method type.bar of <class '__main__.Foo'>>
domanda un po 'correlato: http://stackoverflow.com/q/8719585 –
@BasSwinckels effetti, ma purtroppo che non fornisce informazioni sulla mia domanda. –
Non correlato, ma il terzo parametro non è il "proprietario". Ciò implica che il proprietario è l'oggetto su cui si trova il descrittore. Piuttosto è il tipo con cui è stato invocato il descrittore. Cioè, se si accede al descrittore tramite una sottoclasse, il terzo parametro sarà la sottoclasse e non la classe genitore (che "possiede" il descrittore). – Dunes