__new__ et autres particularités du nouveau modèle objet
3 réponses
JB Richet
bonjour,
Pour entrer dans des discussions un peu plus précises que ce à quoi
invitait mon mail de lundi, voici quelques interrogations plus ponctuelles :
1) la méthode __new__
le prédicat :
"""
x = C(23)
équivaut à
x = C.__new__(C,23)
if isinstance(x, C):
C.__init__(x, 23)
"""
rend les choses assez claires sur le principe. Mais dans quels cas
a-t-on besoin de redéfinir la fonction __new__ lorsque l'on crée une
nouvelle classe ?
Le livre "Python en concentré" (aux éditions O'Reilly) donne l'exemple
du singleton. J'arrive à suivre, mais je ne vois pas à quoi sert d'avoir
au plus une instance d'une classe. Et puis il y a sûrement d'autrs cas
où redéfinir __new__ doit être utile...
2) l'attribut __slots__
si un attribut __slots__ est présent dans la classe, on ne peut ajouter
d'autres attributs à l'instance de cette classe.
les auteurs de mon bouquin disent que cela permet de gagner un peu en
mémoire utilisée par instance, mais que ce n'est valable que s'il y a
vraiment plusieurs millions d'instances.
je vois un autre avantage : éviter des attributions erronées en dehors
du corps de la classe, genre
x.argment = truc
alors que la classe de x ne définit qu'un attribut 'argument'...
est-ce pertinant d'utiliser __slot__ dans ce sens ? ou y a-t-il une
autre solution plus élégante ?
3) le type super
ok pour l'ordre de recherche des espaces de noms différents du modèle
classique. mais le type super me pose problème : il semble que lorsqu'il
intervient, le compilateur ne s'arrête pas à la première occurence de
l'attribut cherché, mais va chercher tous ceux présent dans l'ensemble
de l'arbre... c'est encore confus pour moi.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Xavier Combelle
Le livre "Python en concentré" (aux éditions O'Reilly) donne l'exemple du singleton. J'arrive à suivre, mais je ne vois pas à quoi sert d'avoir au plus une instance d'une classe. Et puis il y a sûrement d'autrs cas où redéfinir __new__ doit être utile...
Il semble que ce soit absoluement nécessaire dans certains cas, pur faire de l'héritage des classes "builtin" voir: http://www.python.org/2.2.3/descrintro.html#__new__
Pour ma part, avec Python, j'ai la démarche suivante, si je ne sais pas à quoi ca peut me servir, je ne m'y intéresse pas, je comprendrais quand j'en aurait vraiement besoin. J'ai l'impression que pour pour 99% du code, les métaclasses ou les __new__ c'est pas utile (au contraire de l'introspection et de __dict__) Il semble que ce soit utile si tu veux faire un framework ou une librairie très spéciale.
je vois un autre avantage : éviter des attributions erronées en dehors du corps de la classe, genre x.argment = truc alors que la classe de x ne définit qu'un attribut 'argument'... est-ce pertinant d'utiliser __slot__ dans ce sens ? ou y a-t-il une autre solution plus élégante ? AMHA, c'est pas trop pythonqiue de faire ça, car ca restreint
l'utilisation de l'objet. Si c'est pour éviter des problème de codage, j'aurait une tendance à utiliser un outil du type PyChecker.
d'après la quick reference de python: Note: According to recent discussions, the real purpose of slots seems still unclear (optimization?), and their use should probably be discouraged.
Pour rajouter la vérification à l'ajout, je pense que quelque chose comme le code suivant est plus explicite.
class tata: def __setattr__(self,name,value): if name not in ("att", "un autre"): raise AttributeError ( "'tata' interdit l'attribut '%s'" % name) self.__dict__[name] = value
titi = tata()
titi.att = "toto" print titi.att
titi.att2 = "toto" print titi.att2
Le livre "Python en concentré" (aux éditions O'Reilly) donne l'exemple
du singleton. J'arrive à suivre, mais je ne vois pas à quoi sert d'avoir
au plus une instance d'une classe. Et puis il y a sûrement d'autrs cas
où redéfinir __new__ doit être utile...
Il semble que ce soit absoluement nécessaire dans certains cas, pur
faire de l'héritage des classes "builtin" voir:
http://www.python.org/2.2.3/descrintro.html#__new__
Pour ma part, avec Python, j'ai la démarche suivante, si je ne sais pas
à quoi ca peut me servir, je ne m'y intéresse pas, je comprendrais quand
j'en aurait vraiement besoin.
J'ai l'impression que pour pour 99% du code, les métaclasses ou les
__new__ c'est pas utile (au contraire de l'introspection et de __dict__)
Il semble que ce soit utile si tu veux faire un framework ou une
librairie très spéciale.
je vois un autre avantage : éviter des attributions erronées en dehors
du corps de la classe, genre
x.argment = truc
alors que la classe de x ne définit qu'un attribut 'argument'...
est-ce pertinant d'utiliser __slot__ dans ce sens ? ou y a-t-il une
autre solution plus élégante ?
AMHA, c'est pas trop pythonqiue de faire ça, car ca restreint
l'utilisation de l'objet. Si c'est pour éviter des problème de codage,
j'aurait une tendance à utiliser un outil du type PyChecker.
d'après la quick reference de python:
Note: According to recent discussions, the real purpose of slots seems
still unclear (optimization?), and their use should probably be discouraged.
Pour rajouter la vérification à l'ajout, je pense que quelque chose
comme le code suivant est plus explicite.
class tata:
def __setattr__(self,name,value):
if name not in ("att", "un autre"):
raise AttributeError (
"'tata' interdit l'attribut '%s'" % name)
self.__dict__[name] = value
Le livre "Python en concentré" (aux éditions O'Reilly) donne l'exemple du singleton. J'arrive à suivre, mais je ne vois pas à quoi sert d'avoir au plus une instance d'une classe. Et puis il y a sûrement d'autrs cas où redéfinir __new__ doit être utile...
Il semble que ce soit absoluement nécessaire dans certains cas, pur faire de l'héritage des classes "builtin" voir: http://www.python.org/2.2.3/descrintro.html#__new__
Pour ma part, avec Python, j'ai la démarche suivante, si je ne sais pas à quoi ca peut me servir, je ne m'y intéresse pas, je comprendrais quand j'en aurait vraiement besoin. J'ai l'impression que pour pour 99% du code, les métaclasses ou les __new__ c'est pas utile (au contraire de l'introspection et de __dict__) Il semble que ce soit utile si tu veux faire un framework ou une librairie très spéciale.
je vois un autre avantage : éviter des attributions erronées en dehors du corps de la classe, genre x.argment = truc alors que la classe de x ne définit qu'un attribut 'argument'... est-ce pertinant d'utiliser __slot__ dans ce sens ? ou y a-t-il une autre solution plus élégante ? AMHA, c'est pas trop pythonqiue de faire ça, car ca restreint
l'utilisation de l'objet. Si c'est pour éviter des problème de codage, j'aurait une tendance à utiliser un outil du type PyChecker.
d'après la quick reference de python: Note: According to recent discussions, the real purpose of slots seems still unclear (optimization?), and their use should probably be discouraged.
Pour rajouter la vérification à l'ajout, je pense que quelque chose comme le code suivant est plus explicite.
class tata: def __setattr__(self,name,value): if name not in ("att", "un autre"): raise AttributeError ( "'tata' interdit l'attribut '%s'" % name) self.__dict__[name] = value
titi = tata()
titi.att = "toto" print titi.att
titi.att2 = "toto" print titi.att2
JB Richet
Xavier Combelle wrote:
Il semble que ce soit absoluement nécessaire dans certains cas, pur faire de l'héritage des classes "builtin" voir: http://www.python.org/2.2.3/descrintro.html#__new__ lien intéressant
Pour ma part, avec Python, j'ai la démarche suivante, si je ne sais pas à quoi ca peut me servir, je ne m'y intéresse pas, je comprendrais quand j'en aurait vraiement besoin. sans doute. je fais pareil, notamment quand je ne connais même pas
l'existence de telle ou telle possibilité. mais quand tu butes, et que tu cmoprends enfin, tu te dis que tu as perdu du temps, et qu'il y a des tas d'autres cas où, sans être indispensemble, la possibilité était plus élégante que ce que tu as fait... mais du point de vu pragmatique, la démarche est certainement la plus efficace.
J'ai l'impression que pour pour 99% du code, les métaclasses ou les __new__ c'est pas utile (au contraire de l'introspection et de __dict__) introspection ? j'en fais peut-être comme M. Jourdain faisait de la
prose... quand au __dict__, j'avoue ne pas m'en servir. Quand en as-tu besoin ?
AMHA, c'est pas trop pythonqiue de faire ça, car ca restreint l'utilisation de l'objet. je me disais bien...
Si c'est pour éviter des problème de codage, j'aurait une tendance à utiliser un outil du type PyChecker. il faut que je m'y colle, oui.
d'après la quick reference de python: Note: According to recent discussions, the real purpose of slots seems still unclear (optimization?), and their use should probably be discouraged. bon ben c'est clair.
Pour rajouter la vérification à l'ajout, je pense que quelque chose comme le code suivant est plus explicite. [...] vu (et compris).
merci à toi. JBR
Xavier Combelle wrote:
Il semble que ce soit absoluement nécessaire dans certains cas, pur
faire de l'héritage des classes "builtin" voir:
http://www.python.org/2.2.3/descrintro.html#__new__
lien intéressant
Pour ma part, avec Python, j'ai la démarche suivante, si je ne sais pas
à quoi ca peut me servir, je ne m'y intéresse pas, je comprendrais quand
j'en aurait vraiement besoin.
sans doute. je fais pareil, notamment quand je ne connais même pas
l'existence de telle ou telle possibilité. mais quand tu butes, et que
tu cmoprends enfin, tu te dis que tu as perdu du temps, et qu'il y a des
tas d'autres cas où, sans être indispensemble, la possibilité était plus
élégante que ce que tu as fait... mais du point de vu pragmatique, la
démarche est certainement la plus efficace.
J'ai l'impression que pour pour 99% du code, les métaclasses ou les
__new__ c'est pas utile (au contraire de l'introspection et de __dict__)
introspection ? j'en fais peut-être comme M. Jourdain faisait de la
prose... quand au __dict__, j'avoue ne pas m'en servir. Quand en as-tu
besoin ?
AMHA, c'est pas trop pythonqiue de faire ça, car ca restreint
l'utilisation de l'objet.
je me disais bien...
Si c'est pour éviter des problème de codage,
j'aurait une tendance à utiliser un outil du type PyChecker.
il faut que je m'y colle, oui.
d'après la quick reference de python:
Note: According to recent discussions, the real purpose of slots seems
still unclear (optimization?), and their use should probably be
discouraged.
bon ben c'est clair.
Pour rajouter la vérification à l'ajout, je pense que quelque chose
comme le code suivant est plus explicite.
[...]
vu (et compris).
Il semble que ce soit absoluement nécessaire dans certains cas, pur faire de l'héritage des classes "builtin" voir: http://www.python.org/2.2.3/descrintro.html#__new__ lien intéressant
Pour ma part, avec Python, j'ai la démarche suivante, si je ne sais pas à quoi ca peut me servir, je ne m'y intéresse pas, je comprendrais quand j'en aurait vraiement besoin. sans doute. je fais pareil, notamment quand je ne connais même pas
l'existence de telle ou telle possibilité. mais quand tu butes, et que tu cmoprends enfin, tu te dis que tu as perdu du temps, et qu'il y a des tas d'autres cas où, sans être indispensemble, la possibilité était plus élégante que ce que tu as fait... mais du point de vu pragmatique, la démarche est certainement la plus efficace.
J'ai l'impression que pour pour 99% du code, les métaclasses ou les __new__ c'est pas utile (au contraire de l'introspection et de __dict__) introspection ? j'en fais peut-être comme M. Jourdain faisait de la
prose... quand au __dict__, j'avoue ne pas m'en servir. Quand en as-tu besoin ?
AMHA, c'est pas trop pythonqiue de faire ça, car ca restreint l'utilisation de l'objet. je me disais bien...
Si c'est pour éviter des problème de codage, j'aurait une tendance à utiliser un outil du type PyChecker. il faut que je m'y colle, oui.
d'après la quick reference de python: Note: According to recent discussions, the real purpose of slots seems still unclear (optimization?), and their use should probably be discouraged. bon ben c'est clair.
Pour rajouter la vérification à l'ajout, je pense que quelque chose comme le code suivant est plus explicite. [...] vu (et compris).
merci à toi. JBR
Xavier Combelle
introspection ? j'en fais peut-être comme M. Jourdain faisait de la prose... quand au __dict__, j'avoue ne pas m'en servir. Quand en as-tu besoin ?
Personnellement, je m'en suis servi pour avoir une configuration sous
forme d'objet.
Par exemple, je voulait pouvoir écrire: if mapping.sens == "get": import sys,os print >>sys.stderr, "rapatrie les donnees"
tout en laissant le paramétrage dans un fichier de donnée.
voici le coeur de mon objet mapping.
keys = "mainframe_prefix prefix sens content".split() for ligne in fichier: #recupere la clef args = [ x.strip() for x in ligne.split(':')] if len(args) == 2: key,value = args assert key in keys,"invalide: %s, permises :%s" % (key,keys) self.__dict__[key] = value
L'avantage, c'est que, si je veux rajouter une option de configuration, je ne change pas le code du parser, et je me contente de l'utiliser. Lorsque je passe mon test unitaire, une erreur se produit à l'execution du programme paramètre, je rajoute la clef dans mon fichier de conf, puis une erreur se produit lors du parsing et je rajoute la clef dans les clefs autorisees et ensuite tout est ok.
Au final, ca m'a donné un code simple, robuste et évolutif.
introspection ? j'en fais peut-être comme M. Jourdain faisait de la
prose... quand au __dict__, j'avoue ne pas m'en servir. Quand en as-tu
besoin ?
Personnellement, je m'en suis servi pour avoir une configuration sous
forme d'objet.
Par exemple, je voulait pouvoir écrire:
if mapping.sens == "get":
import sys,os
print >>sys.stderr, "rapatrie les donnees"
tout en laissant le paramétrage dans un fichier de donnée.
voici le coeur de mon objet mapping.
keys = "mainframe_prefix prefix sens content".split()
for ligne in fichier:
#recupere la clef
args = [ x.strip() for x in ligne.split(':')]
if len(args) == 2:
key,value = args
assert key in keys,"invalide: %s, permises :%s" % (key,keys)
self.__dict__[key] = value
L'avantage, c'est que, si je veux rajouter une option de configuration,
je ne change pas le code du parser, et je me contente de l'utiliser.
Lorsque je passe mon test unitaire, une erreur se produit à l'execution
du programme paramètre, je rajoute la clef dans mon fichier de conf,
puis une erreur se produit lors du parsing et je rajoute la clef dans
les clefs autorisees et ensuite tout est ok.
Au final, ca m'a donné un code simple, robuste et évolutif.
introspection ? j'en fais peut-être comme M. Jourdain faisait de la prose... quand au __dict__, j'avoue ne pas m'en servir. Quand en as-tu besoin ?
Personnellement, je m'en suis servi pour avoir une configuration sous
forme d'objet.
Par exemple, je voulait pouvoir écrire: if mapping.sens == "get": import sys,os print >>sys.stderr, "rapatrie les donnees"
tout en laissant le paramétrage dans un fichier de donnée.
voici le coeur de mon objet mapping.
keys = "mainframe_prefix prefix sens content".split() for ligne in fichier: #recupere la clef args = [ x.strip() for x in ligne.split(':')] if len(args) == 2: key,value = args assert key in keys,"invalide: %s, permises :%s" % (key,keys) self.__dict__[key] = value
L'avantage, c'est que, si je veux rajouter une option de configuration, je ne change pas le code du parser, et je me contente de l'utiliser. Lorsque je passe mon test unitaire, une erreur se produit à l'execution du programme paramètre, je rajoute la clef dans mon fichier de conf, puis une erreur se produit lors du parsing et je rajoute la clef dans les clefs autorisees et ensuite tout est ok.
Au final, ca m'a donné un code simple, robuste et évolutif.