J'ai débuté le python sérieusement il y a de cela quelques mois et il me
sert principalement pour faire des scripts d'administrations. (Pour la
petite histoire, je faisais mes script en php avant, mais l'admin de mon
école à enlever le support php pour la ligne de commande, j'ai du changé
de langage et j'ai découvert avec plaisir le python, qui si il ne
remplacera jamais le php pour le web, est devenu mon language de
prédilection en matière de scripts et petits programmes.)
Cependant je compte me lancer dans quelque chose de plus gros (mon rève
a toujours été de faire un jeu) et pour cela j'ai besoin de faire le
point sur certains comportements qui ne m'on jamais embétés sur des
scripts de 20 lignes mais qui risques de peser lourd par la suite. Plus
précisement, je prefere me lancer dans un gros dev en sachant ce que va
faire ce que j'écris et non pas comme ce qui se passe actuellement ou je
test et je vois ce qui se passe. Pour l'exemple j'ai codé une fonction
récursive de gestion de graph dernièrement et je ne comprand pas comment
elle fonctionne, mais elle fonctionne...
Avant toute chose, je tient à signaler que mes attentes vis à vis d'un
comportement sont fortement influencées par les langages que je
maitrises, Php principalement. Je suis pret à changer "d'attentes" à la
seule condition que je comprenne la philosophie du problème.
1) J'ai quelques problèmes pour comprandre le systeme de "copie" de
variables, exemple:
>>> a = 0; b = a; b = 2; (a,b)
(0, 2)
>>> a = "a"; b = a ; b = "b"; (a,b)
('a', 'b')
>>> a = (1,); b = a; b = (2,); (a,b)
((1,), (2,))
>>> a = [0]; b = a;b = [1]; a,b
([0], [1])
>>> a = [0]; b = a;b[0] = 1; a,b
([1], [1]) # Ici ce résultat me choque...
D'un autre coté, cela peu sembler logique, dans tous les autres cas je
réaffecte b, alors que là je ne fait que modifier un élément de b, donc.
Comment gérer-vous ce comportement bizarre (à mon sens, je doute qu'il
soit bizarre pour vous, mais alors expliquer moi pourquoi il n'est pas
bizarre...)
2) Un autre exemple qui me rend dingue :
def double(i):
i *= 2
return i
a = 1
print double(a) # 2 attendu OK
print a # 1 attendu OK
a = [1]
print double(a) # [1,1] OK
print a # Je m'attendais à [1], j'ai [1,1]
# ---
def double2(i):
i = i * 2
return i
a = [1]
print double2(a) # [1,1] OK
print a # Correspond à mon attente,
# mais pas au test précedent.
Pourquoi donc les operateurs ne reagissent pas de la même façon alors
qu'ils sont sensés être synonymes ?
3) Un troisème exemple, j'ai voulu faire une fonction prenant comme
paramétre d'entrée optionel une liste :
def func(a = []): # Valeur par defaut, la liste vide
a.append(len(a))
return a
z = func()
print z # Attendu [0], OK
y = func()
print y # Attendu [0], obtenu [0,1]
b = range(3)
print func(b) # Attendu [0,1,2,3] OK
print b # Obtenu [0,1,2,3], attendu [0,1,2]
Donc première chose, apparament lorsque l'on alloue comme valeur par
defaut une liste, elle agit comme un élement "static" ? J'ai lu cela
quelque part dans la doc, je le conçoit mais j'aimerais comprandre
Pourquoi ? (Je n'arrive pas à assimiler des choses qui n'ont pas de
logique, je cherche donc la logique derrière)
Dans le cas du deuxième test, apparament la variable b est modifiée par
l'appel à la fonction func. Il s'agit d'une variable "mutable", donc
c'est un comportement normal vis à vis de la doc, mais pas vis à vis de
ce que j'attend, pourquoi ?
Comment faites vous pour faire une fonction qui prend en paramètre une
variable et renvoie une variable y ressemblant, mais modifiée. Passez
vous obligatoirement pas copy.deepcopy ? Dans le cas de liste simple on
peux facilement faire un a = b[:], mais dans le cas de listes complexes,
cela devient plus corriaces. Comment expliquez vous ce concept de copie
par réference à tout bout de champs ?
Bref, pas vraiment de question, juste besoin de comprandre la
philosophie qui se cache derrière ces comportements surprenants.
Merci si vous pouvez éclairer ma lanterne ou me rediriger vers une doc
qui le fera...
Encore désolé pour les fautes qui se cachent dans ce que j'écris.
--
Guillaume.
Ah bon ? A part les instructions et les expressions, qu'est-ce qui n'est pas objet en Python ?
Les entiers et les flotants...
dir(3) ['__abs__', '__add__', ...]
3.__class__ File "<stdin>", line 1
3.__class__ ^ SyntaxError: invalid syntax
3.__add_(4) File "<stdin>", line 1
3.__add_(4) ^ SyntaxError: invalid syntax
donc tout n'est pas objet.
Cette erreur vient d'une ambigüité dans la syntaxe: Quand python voit le point après le 3, il s'attend à avoir un 'float' avec sa partie décimale. Il suffit de mettre un espace ou des parenthèses:
3 .__class__ <type 'int'>
(3).__class__ <type 'int'>
3..__class__ <type 'float'>
(3).__add__(4) 7
donc tout n'est pas objet. Si!
Amaury
Jerome wrote:
(snip)
Ah bon ? A part les instructions et les expressions, qu'est-ce qui
n'est pas objet en Python ?
Les entiers et les flotants...
dir(3)
['__abs__', '__add__', ...]
3.__class__
File "<stdin>", line 1
3.__class__
^
SyntaxError: invalid syntax
3.__add_(4)
File "<stdin>", line 1
3.__add_(4)
^
SyntaxError: invalid syntax
donc tout n'est pas objet.
Cette erreur vient d'une ambigüité dans la syntaxe: Quand python voit le
point après le 3, il s'attend à avoir un 'float' avec sa partie
décimale. Il suffit de mettre un espace ou des parenthèses:
Ah bon ? A part les instructions et les expressions, qu'est-ce qui n'est pas objet en Python ?
Les entiers et les flotants...
dir(3) ['__abs__', '__add__', ...]
3.__class__ File "<stdin>", line 1
3.__class__ ^ SyntaxError: invalid syntax
3.__add_(4) File "<stdin>", line 1
3.__add_(4) ^ SyntaxError: invalid syntax
donc tout n'est pas objet.
Cette erreur vient d'une ambigüité dans la syntaxe: Quand python voit le point après le 3, il s'attend à avoir un 'float' avec sa partie décimale. Il suffit de mettre un espace ou des parenthèses:
Lisez attentivement le message d'erreur : cela ne marche pas non pas parce que "int" est immuable mais parce qu'il est "built-in" c'est-à-dire écrit en C.
Dommage :(
Pas si sûr. Il y a eu des discussions sur les forums/NG anglophones à ce sujet. La question est de savoir : si tu pouvais le faire, voudrais-tu que: - ta classe modifiée le soit uniquement pour ton module ? mais alors quel est l'intérêt ? ne pas devoir taper integer(2) au lien de 2 ? Oui c'est vrai mais: "Readability counts." The Zen of Python, by Tim Peters - modifier le comportement de int dans toute l'application (comme on peut le faire en Ruby je pense). C'est vraiment contre-pythonesque si je peux me permettre et la tendance serait plutôt d'empêcher d'écraser les built-in même localement (mais évidemment tu peux toujours réécrire un Python à ta sauce bien que ce soit une trés mauvaise idée). L'idée c'est que dans ce cas, celui qui écrit (et qui lit ce qui est encore plus important car comme le soulignait Alex Martelli - je crois - on lit bien plus de code qu'on en écrit) du code ne sait pas comment il sera exécuté. N'oublions jamais: "Explicit is better than implicit" The Zen of Python, by Tim Peters
Si la classe d'origine est en python il ne devrait pas y avoir de problème. Vous pouvez aussi regarder du côté de la délégation.
Merci.
F. Petitjean wrote:
Lisez attentivement le message d'erreur : cela ne marche pas non pas
parce que "int" est immuable mais parce qu'il est "built-in"
c'est-à-dire écrit en C.
Dommage :(
Pas si sûr. Il y a eu des discussions sur les forums/NG anglophones à ce
sujet. La question est de savoir : si tu pouvais le faire, voudrais-tu que:
- ta classe modifiée le soit uniquement pour ton module ? mais alors
quel est l'intérêt ? ne pas devoir taper integer(2) au lien de 2 ? Oui
c'est vrai mais:
"Readability counts." The Zen of Python, by Tim Peters
- modifier le comportement de int dans toute l'application (comme on
peut le faire en Ruby je pense). C'est vraiment contre-pythonesque si je
peux me permettre et la tendance serait plutôt d'empêcher d'écraser les
built-in même localement (mais évidemment tu peux toujours réécrire un
Python à ta sauce bien que ce soit une trés mauvaise idée). L'idée c'est
que dans ce cas, celui qui écrit (et qui lit ce qui est encore plus
important car comme le soulignait Alex Martelli - je crois - on lit bien
plus de code qu'on en écrit) du code ne sait pas comment il sera
exécuté. N'oublions jamais:
"Explicit is better than implicit" The Zen of Python, by Tim Peters
Si la classe d'origine est en python il ne devrait pas y avoir de
problème. Vous pouvez aussi regarder du côté de la délégation.
Lisez attentivement le message d'erreur : cela ne marche pas non pas parce que "int" est immuable mais parce qu'il est "built-in" c'est-à-dire écrit en C.
Dommage :(
Pas si sûr. Il y a eu des discussions sur les forums/NG anglophones à ce sujet. La question est de savoir : si tu pouvais le faire, voudrais-tu que: - ta classe modifiée le soit uniquement pour ton module ? mais alors quel est l'intérêt ? ne pas devoir taper integer(2) au lien de 2 ? Oui c'est vrai mais: "Readability counts." The Zen of Python, by Tim Peters - modifier le comportement de int dans toute l'application (comme on peut le faire en Ruby je pense). C'est vraiment contre-pythonesque si je peux me permettre et la tendance serait plutôt d'empêcher d'écraser les built-in même localement (mais évidemment tu peux toujours réécrire un Python à ta sauce bien que ce soit une trés mauvaise idée). L'idée c'est que dans ce cas, celui qui écrit (et qui lit ce qui est encore plus important car comme le soulignait Alex Martelli - je crois - on lit bien plus de code qu'on en écrit) du code ne sait pas comment il sera exécuté. N'oublions jamais: "Explicit is better than implicit" The Zen of Python, by Tim Peters
Si la classe d'origine est en python il ne devrait pas y avoir de problème. Vous pouvez aussi regarder du côté de la délégation.
Merci.
Guillaume Bouchard
kaerbuhez wrote:
... "Readability counts." The Zen of Python, by Tim Peters ... "Explicit is better than implicit" The Zen of Python, by Tim Peters
C'est encore un detail de ce qui me chagrinait dans le Python qui viens de disparaitre, tu m'as convaincu.
Bon, faut que je trouve des defauts qui tiennent la route à ce langage, sinon je vais vraiment finir fan.
-- Guillaume.
kaerbuhez wrote:
...
"Readability counts." The Zen of Python, by Tim Peters
...
"Explicit is better than implicit" The Zen of Python, by Tim Peters
C'est encore un detail de ce qui me chagrinait dans le Python qui viens
de disparaitre, tu m'as convaincu.
Bon, faut que je trouve des defauts qui tiennent la route à ce langage,
sinon je vais vraiment finir fan.
t = Truc(42) t + t <__main__.Truc object at 0x4032ba0c>
(t + t).val 84
En l'occurrence, c'est effectivement une méthode d'instance, pas une classmethod. Mais bon...
Mais c'est peut-être juste caché. Même pas...
Mais je peux me tromper et si tu as une doc qui explique clairement les concepts objets de python, je suis preneur. Tout est sur python.org
probablement pour des raisons de performances. En Smalltalk qui est réellement pur objet tu n'as que des références.
Je suis d'accord que Smalltalk soit encore plus extrêmistement OO que Python, mais pour ce qui est des références, tu fais erreur : en Python, il n'y a que des références.
ok, mea culpa. C'est le concept d'objet immutable dont je ne vois pas l'utilité pour l'instant.
Disons que c'est d'abord et avant tout un problème d'implémentation...
Je ne sais pas s'il y a une vraie raison mais tu peux voir venir un autre problème qui est de réussir à passer un objet de type immutable en référence...
C'est pourtant ce que tu fais chaque fois que tu passes un objet immutable à une fonction.
même problème en fait. Comment faire pour supprimer le caractère immutable d'un objet. En le wrappant dans un objet d'un type mutable. La solution la plus
bestialement con étant de passer une liste avec l'objet en question comme seul élément.
L'exemple le plus simple auquel je pense c'est comment passer un entier en paramètre d'une fonction et réussir à le modifier dans la fonction.
def mutatis(wrappedInt): ... wrappedInt[0] += 42
...
mutant = [0] mutatis(mutant) mutant [42]
HTH Bruno
bruno modulix wrote:
Jerome wrote:
(snip)
lol, tu fais les questions et les réponses.
Pour moi c'est une incohérence de python qui n'a pas une vision
totalement objet,
Ah bon ? A part les instructions et les expressions, qu'est-ce qui
n'est pas objet en Python ?
Les types de bases comme int, float ou bool par exemple ne sont pas des
objets.
Hem...
i = 42
i
42
i.__class__.__name__
'int'
Ou plutôt tu ne peux pas spécialiser la classe des entiers par
exemple
class MyInt(int):
... pass
...
i = MyInt(24)
i
24
car tu n'as pas accès la définition de la classe, si elle existe.
Use the code, Luke.
Les opérateurs ne sont pas des méthodes de classes à ce que j'ai lu dans
la doc.
t = Truc(42)
t + t
<__main__.Truc object at 0x4032ba0c>
(t + t).val
84
En l'occurrence, c'est effectivement une méthode d'instance, pas une
classmethod. Mais bon...
Mais c'est peut-être juste caché.
Même pas...
Mais je peux me tromper et si tu as une doc qui explique clairement les
concepts objets de python, je suis preneur.
Tout est sur python.org
probablement pour des raisons de performances. En Smalltalk qui est
réellement pur objet tu n'as que des références.
Je suis d'accord que Smalltalk soit encore plus extrêmistement OO que
Python, mais pour ce qui est des références, tu fais erreur : en
Python, il n'y a que des références.
ok, mea culpa. C'est le concept d'objet immutable dont je ne vois pas
l'utilité pour l'instant.
Disons que c'est d'abord et avant tout un problème d'implémentation...
Je ne sais pas s'il y a une vraie raison mais tu peux voir venir un
autre problème qui est de réussir à passer un objet de type immutable
en référence...
C'est pourtant ce que tu fais chaque fois que tu passes un objet
immutable à une fonction.
même problème en fait. Comment faire pour supprimer le caractère
immutable d'un objet.
En le wrappant dans un objet d'un type mutable. La solution la plus
bestialement con étant de passer une liste avec l'objet en question
comme seul élément.
L'exemple le plus simple auquel je pense c'est comment passer un entier
en paramètre d'une fonction et réussir à le modifier dans la fonction.
t = Truc(42) t + t <__main__.Truc object at 0x4032ba0c>
(t + t).val 84
En l'occurrence, c'est effectivement une méthode d'instance, pas une classmethod. Mais bon...
Mais c'est peut-être juste caché. Même pas...
Mais je peux me tromper et si tu as une doc qui explique clairement les concepts objets de python, je suis preneur. Tout est sur python.org
probablement pour des raisons de performances. En Smalltalk qui est réellement pur objet tu n'as que des références.
Je suis d'accord que Smalltalk soit encore plus extrêmistement OO que Python, mais pour ce qui est des références, tu fais erreur : en Python, il n'y a que des références.
ok, mea culpa. C'est le concept d'objet immutable dont je ne vois pas l'utilité pour l'instant.
Disons que c'est d'abord et avant tout un problème d'implémentation...
Je ne sais pas s'il y a une vraie raison mais tu peux voir venir un autre problème qui est de réussir à passer un objet de type immutable en référence...
C'est pourtant ce que tu fais chaque fois que tu passes un objet immutable à une fonction.
même problème en fait. Comment faire pour supprimer le caractère immutable d'un objet. En le wrappant dans un objet d'un type mutable. La solution la plus
bestialement con étant de passer une liste avec l'objet en question comme seul élément.
L'exemple le plus simple auquel je pense c'est comment passer un entier en paramètre d'une fonction et réussir à le modifier dans la fonction.
def mutatis(wrappedInt): ... wrappedInt[0] += 42
...
mutant = [0] mutatis(mutant) mutant [42]
HTH Bruno
Bruno Desthuilliers
Jerome wrote:
Les types de bases comme int, float ou bool par exemple ne sont pas des objets. Ou plutôt tu ne peux pas spécialiser la classe des entiers par exemple car tu n'as pas accès la définition de la classe, si elle existe.
Je suis pas certain que j'ai comprit ce que tu as écris, mais je te laisse faire un dir(5) par exemple, tu veras que c'est bien une classe...
Que ce n'est pas un vrai **objet**
Ah bon ? En quoi ?
Ne pas confondre classe et objet. Dans ton exemple, int.__add__ est une fonction statique (équivalent à static en Java ou staticmethod en Python, voire peut-être une classmethod ). Si c'était vraiment objet tu ferais 2.__add__(5) ce qui ne marche pas !
Exemple que Python est tordu :
3.__add__(5) File "<stdin>", line 1
3.__add__(5) ^ SyntaxError: invalid syntax
getattr(3,'__add__')(5) 8
getattr(3,'__add__') <method-wrapper object at 0x007EBF50>
Donc les objets de bases ne sont pas des vrais objets...
En quoi le fait que certaines classes aient un comportement spécifique entraîne-t'il que les instances de ces classes ne soient pas de "vrais" objets ? Rien ne t'empêche d'implémenter toi-même (et en 100% Python) des classes dont les instances se comportent de la même façon - donc ton raisonnement ne tient pas.
Jerome wrote:
Les types de bases comme int, float ou bool par exemple ne sont pas
des objets. Ou plutôt tu ne peux pas spécialiser la classe des
entiers par exemple car tu n'as pas accès la définition de la classe,
si elle existe.
Je suis pas certain que j'ai comprit ce que tu as écris, mais je te
laisse faire un dir(5) par exemple, tu veras que c'est bien une classe...
Que ce n'est pas un vrai **objet**
Ah bon ? En quoi ?
Ne pas confondre classe et objet.
Dans ton exemple, int.__add__ est une fonction statique (équivalent à
static en Java ou staticmethod en Python, voire peut-être une
classmethod ). Si c'était vraiment objet tu ferais 2.__add__(5) ce qui
ne marche pas !
Exemple que Python est tordu :
3.__add__(5)
File "<stdin>", line 1
3.__add__(5)
^
SyntaxError: invalid syntax
getattr(3,'__add__')(5)
8
getattr(3,'__add__')
<method-wrapper object at 0x007EBF50>
Donc les objets de bases ne sont pas des vrais objets...
En quoi le fait que certaines classes aient un comportement spécifique
entraîne-t'il que les instances de ces classes ne soient pas de "vrais"
objets ? Rien ne t'empêche d'implémenter toi-même (et en 100% Python)
des classes dont les instances se comportent de la même façon - donc ton
raisonnement ne tient pas.
Les types de bases comme int, float ou bool par exemple ne sont pas des objets. Ou plutôt tu ne peux pas spécialiser la classe des entiers par exemple car tu n'as pas accès la définition de la classe, si elle existe.
Je suis pas certain que j'ai comprit ce que tu as écris, mais je te laisse faire un dir(5) par exemple, tu veras que c'est bien une classe...
Que ce n'est pas un vrai **objet**
Ah bon ? En quoi ?
Ne pas confondre classe et objet. Dans ton exemple, int.__add__ est une fonction statique (équivalent à static en Java ou staticmethod en Python, voire peut-être une classmethod ). Si c'était vraiment objet tu ferais 2.__add__(5) ce qui ne marche pas !
Exemple que Python est tordu :
3.__add__(5) File "<stdin>", line 1
3.__add__(5) ^ SyntaxError: invalid syntax
getattr(3,'__add__')(5) 8
getattr(3,'__add__') <method-wrapper object at 0x007EBF50>
Donc les objets de bases ne sont pas des vrais objets...
En quoi le fait que certaines classes aient un comportement spécifique entraîne-t'il que les instances de ces classes ne soient pas de "vrais" objets ? Rien ne t'empêche d'implémenter toi-même (et en 100% Python) des classes dont les instances se comportent de la même façon - donc ton raisonnement ne tient pas.
Bruno Desthuilliers
kaerbuhez wrote:
... "Readability counts." The Zen of Python, by Tim Peters ... "Explicit is better than implicit" The Zen of Python, by Tim Peters
C'est encore un detail de ce qui me chagrinait dans le Python qui viens de disparaitre, tu m'as convaincu.
Bon, faut que je trouve des defauts qui tiennent la route à ce langage, Il y en a, mais pas assez pour ne pas...
sinon je vais vraiment finir fan. Trop tard !-)
kaerbuhez wrote:
...
"Readability counts." The Zen of Python, by Tim Peters
...
"Explicit is better than implicit" The Zen of Python, by Tim Peters
C'est encore un detail de ce qui me chagrinait dans le Python qui viens
de disparaitre, tu m'as convaincu.
Bon, faut que je trouve des defauts qui tiennent la route à ce langage,
Il y en a, mais pas assez pour ne pas...
... "Readability counts." The Zen of Python, by Tim Peters ... "Explicit is better than implicit" The Zen of Python, by Tim Peters
C'est encore un detail de ce qui me chagrinait dans le Python qui viens de disparaitre, tu m'as convaincu.
Bon, faut que je trouve des defauts qui tiennent la route à ce langage, Il y en a, mais pas assez pour ne pas...
sinon je vais vraiment finir fan. Trop tard !-)
Bruno Desthuilliers
Jerome wrote: (snip)
lol, tu fais les questions et les réponses. Pour moi c'est une incohérence de python qui n'a pas une vision totalement objet,
Ah bon ? A part les instructions et les expressions, qu'est-ce qui n'est pas objet en Python ?
Les entiers et les flotants...
Erreur...
dir(3) ['__abs__', '__add__', ...]
3.__class__ File "<stdin>", line 1
3.__class__ ^ SyntaxError: invalid syntax
3.__add_(4) File "<stdin>", line 1
3.__add_(4) ^ SyntaxError: invalid syntax
donc tout n'est pas objet.
Je suis d'accord que Smalltalk soit encore plus extrêmistement OO que Python, mais pour ce qui est des références, tu fais erreur : en Python, il n'y a que des références.
La preuve que non plus haut...
La preuve que si, voir d'autres posts dans ce thread.
Jerome wrote:
(snip)
lol, tu fais les questions et les réponses.
Pour moi c'est une incohérence de python qui n'a pas une vision
totalement objet,
Ah bon ? A part les instructions et les expressions, qu'est-ce qui
n'est pas objet en Python ?
Les entiers et les flotants...
Erreur...
dir(3)
['__abs__', '__add__', ...]
3.__class__
File "<stdin>", line 1
3.__class__
^
SyntaxError: invalid syntax
3.__add_(4)
File "<stdin>", line 1
3.__add_(4)
^
SyntaxError: invalid syntax
donc tout n'est pas objet.
Je suis d'accord que Smalltalk soit encore plus extrêmistement OO que
Python, mais pour ce qui est des références, tu fais erreur : en
Python, il n'y a que des références.
La preuve que non plus haut...
La preuve que si, voir d'autres posts dans ce thread.
lol, tu fais les questions et les réponses. Pour moi c'est une incohérence de python qui n'a pas une vision totalement objet,
Ah bon ? A part les instructions et les expressions, qu'est-ce qui n'est pas objet en Python ?
Les entiers et les flotants...
Erreur...
dir(3) ['__abs__', '__add__', ...]
3.__class__ File "<stdin>", line 1
3.__class__ ^ SyntaxError: invalid syntax
3.__add_(4) File "<stdin>", line 1
3.__add_(4) ^ SyntaxError: invalid syntax
donc tout n'est pas objet.
Je suis d'accord que Smalltalk soit encore plus extrêmistement OO que Python, mais pour ce qui est des références, tu fais erreur : en Python, il n'y a que des références.
La preuve que non plus haut...
La preuve que si, voir d'autres posts dans ce thread.
Laurent Pointal
Guillaume Bouchard wrote:
...zip...
Pour les passages de paramètres, la page suivane peut aider: http://wikipython.flibuste.net/moin.py/QuestionsGenerales
LP.
Guillaume Bouchard wrote:
...zip...
Pour les passages de paramètres, la page suivane peut aider:
http://wikipython.flibuste.net/moin.py/QuestionsGenerales