J'ai eu la chance d'écrire une description de Python, et quand j'ai essayé d'écrire une description sur les propriétés,
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
"Quoi?" Comment expliquer cela? J'ai pensé.
Alors, qu'est-ce qui ne va pas? Au fait, Python avait-il une surcharge?
Oui, la partie suivante semble que vous pouvez définir la méthode "même nom mais nombre d'arguments différent" pour le nom (soi) et le nom (soi, nom).
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
Mais vous ne pouvez pas faire cela avec Python. Si vous définissez une méthode avec le même nom, elle sera écrasée par celle définie plus tard (plus précisément, l'attribut du nom de la méthode pointera vers l'objet fonction défini ultérieurement).
Bien entendu, les deux méthodes ci-dessus sont utilisées. Vous pouvez voir que chaque méthode est exécutée si vous préparez l'impression.
Au fait, je me demandais comment écrire @ name.setter. Parce que la partie du nom change en fonction de la propriété.
Résolvons le mystère. Tout d'abord, passons en revue les décorateurs.
@property
def name(self):
return self._name
La description est presque la même que la suivante.
def name(self):
return self._name
name = property(name)
En d'autres termes, le nom sur le côté droit de la troisième ligne est un objet fonction, mais le nom une fois l'affectation terminée sur le côté gauche est un objet de propriété.
Je suis curieux de savoir comment l'écrire, mais convertissons la description suivante avec la même idée.
@name.setter
def name(self, name):
self._name = name
Je me sens comme cela.
def name_setter(self, name):
self._name = name
name = name.setter(name_setter)
Dout (rires). Le nom de la méthode est défini sur name_setter, mais c'est pour que la troisième ligne puisse être exécutée correctement. En fait, si vous regardez la partie description du décorateur dans le document officiel,
Sauf que l'ancien code ne lie pas temporairement la fonction d'origine au nom func.
Il est devenu. En d'autres termes, lors de l'utilisation d'un décorateur, la méthode nommée name n'est pas définie (le nom nommé name défini par @property n'est pas écrasé).
Résumé,
Cela signifie que.
property.setter
Maintenant, si vous savez quelle est la méthode setter de la classe de propriété, la solution est. Pour trouver la réponse, nous devons entrer dans l'implémentation Python. L'implémentation de la classe de propriété peut être trouvée dans Objects / descrobject.c. Si vous omettez les détails de l'implémentation et ne collez que les points principaux,
static PyObject *
property_setter(PyObject *self, PyObject *setter)
{
return property_copy(self, NULL, setter, NULL);
}
Il s'agit de l'implémentation C qui correspond à la méthode setter de la classe de propriété. Donc, property_copy.
static PyObject *
property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
{
propertyobject *pold = (propertyobject *)old;
PyObject *new, *type, *doc;
type = PyObject_Type(old);
if (type == NULL)
return NULL;
if (get == NULL || get == Py_None) {
Py_XDECREF(get);
get = pold->prop_get ? pold->prop_get : Py_None;
}
if (set == NULL || set == Py_None) {
Py_XDECREF(set);
set = pold->prop_set ? pold->prop_set : Py_None;
}
if (del == NULL || del == Py_None) {
Py_XDECREF(del);
del = pold->prop_del ? pold->prop_del : Py_None;
}
if (pold->getter_doc && get != Py_None) {
/* make _init use __doc__ from getter */
doc = Py_None;
}
else {
doc = pold->prop_doc ? pold->prop_doc : Py_None;
}
new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Py_DECREF(type);
if (new == NULL)
return NULL;
return new;
}
C'est un peu long, mais pour résumer ce que je fais
Je fais ça. Cela signifie que la méthode de propriété renvoyée a des getters et des setters définis.
En outre, à propos de la question "Je comprends que l'objet de propriété est défini, mais comment cela fonctionne-t-il pour qu'il puisse être référencé et attribué?" /qiita.com/knzm/items/a8a0fead6e1706663c22) Veuillez vous y référer.
Pour résumer l'histoire.
--Question ―― La description de la propriété ressemble à une surcharge, mais Python pourriez-vous le faire?
À propos, l'explication de la propriété que j'ai initialement essayé d'écrire est
Vous ne connaissez toujours pas trop Python pour expliquer cela
J'ai rendu le thé boueux comme ça (rires)
Recommended Posts