debutant python, DP

debutant python, DP - Python - Programmation

Marsh Posté le 19-08-2007 à 15:16:35    

J'ai une classe Maclasse qui a des attributs predefinis tel que
 
class Maclase:
 
    def __init__(self,attributA=1,attibutB="", attibutC=[] )
        self.attA=attributA
        self.attB=attributB
        self.attB=attributC
 
au moment de l'execution du progamme j'aurai besoin d'instancier un objet de cette classe mais avec des attibuts supplementaires  
 
j'aurais besoin au final d'instancier de cette maniere
 
objet1=Maclasse(attibuA=1, attibutB="chaine", attibutC=[1,2,3], nouveauattribut=22)
 
j'ai pense a deriver la classe pour rajouter un nouvel attribut au cours de l'execution du progamme mais je vois pas comment le faire de maniere elegante puisque je vais avoir des objets avec des attributs en plus qui peuvent etre totalements differents
 
ca devient de la meta prog la , un patron de conception a utiliser ??

Reply

Marsh Posté le 19-08-2007 à 15:16:35   

Reply

Marsh Posté le 20-08-2007 à 10:43:15    

flashball a écrit :

J'ai une classe Maclasse qui a des attributs predefinis tel que
 
class Maclase:
 
    def __init__(self,attributA=1,attibutB="", attibutC=[] )
        self.attA=attributA
        self.attB=attributB
        self.attB=attributC
 
au moment de l'execution du progamme j'aurai besoin d'instancier un objet de cette classe mais avec des attibuts supplementaires  
 
j'aurais besoin au final d'instancier de cette maniere
 
objet1=Maclasse(attibuA=1, attibutB="chaine", attibutC=[1,2,3], nouveauattribut=22)
 
j'ai pense a deriver la classe pour rajouter un nouvel attribut au cours de l'execution du progamme mais je vois pas comment le faire de maniere elegante puisque je vais avoir des objets avec des attributs en plus qui peuvent etre totalements differents
 
ca devient de la meta prog la , un patron de conception a utiliser ??


 
Si tes objets avec de nouveaux attributs sont totalement différents des objets sans attribut, c'est qu'il ne s'agit pas du même objet donc qu'il te faut créer une autre classe pour ces objets là.
 
Sinon pourquoi ne pas mettre tous tes attributs dans la classe principale, quitte à ce que les objets qui n'en ont pas besoin aient cet attribut à vide par défaut
 

Code :
  1. class Maclase:
  2.    def __init__(self,attributA=1,attibutB="", attibutC=[], nouveauAttribut=0)
  3.        self.attA=attributA
  4.        self.attB=attributB
  5.        self.attB=attributC
  6.        self.nouveauAtt=nouveauAttribut
  7.  
  8. objet1=Maclasse(1, "chaine", [1,2,3])
  9. objet2=Maclasse(2, "chaine suite", [4, 5, 6], 22)


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 20-08-2007 à 12:44:16    

  • Si tu as besoin de faire un truc pareil, c'est probablement que ta conception n'est pas correcte, soit que ta classe fait des choses qu'elle ne devrait pas faire, soit que tu devrais utiliser autre chose qu'une classe
  • Une liste vide comme argument par défaut est une très mauvaise idée, ça va te pêter à la gueule
  • Pas besoin de métaprogrammation pour faire ça:
Code :
  1. >>> class Test(object):
  2.     def __init__(self, a=1, b="", c=[], **kwargs):
  3.         self.a = a
  4.         self.b = b
  5.         self.c = c
  6.         self.__dict__.update(kwargs)
  7.  
  8.         
  9. >>> t = Test(1, "foo", "bar", foo="bar", qux="quux" )
  10. >>> t.foo
  11. 'bar'
  12. >>> t.qux
  13. 'quux'
  14. >>> t.a
  15. 1
  16. >>> t.b
  17. 'foo'
  18. t


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 20-08-2007 à 16:59:39    

masklinn a écrit :

Code :
  1. >>> class Test(object):
  2.     def __init__(self, a=1, b="", c=[], **kwargs):
  3.         self.a = a
  4.         self.b = b
  5.         self.c = c
  6.         self.__dict__.update(kwargs)



 
Ahah... explique-moi donc ce "**kwargs" ? Je présume qu'il ne s'agit pas d'un pointeur sur un pointeur... ;)  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 20-08-2007 à 18:02:36    

Sve@r a écrit :


 
Ahah... explique-moi donc ce "**kwargs" ? Je présume qu'il ne s'agit pas d'un pointeur sur un pointeur... ;)  


Nope.
 
Dans les listes d'arguments python a deux marqueurs magiques, * et ** (habituellement utilisés avec les noms args et kwargs, respectivement, donc *args ou **kwargs, ce n'est néamoins qu'une convention).
 
Leurs rôles sont respectivement de récupérer les attributs positionnels (args) non spécifiés et les arguments nommés (kwargs, ou KeyWord ARGumentS) non spécifiés.
 
Ils servent de catchall pour respectivement les arguments positionnels (e.g. foo(1, 5, "bleh", "pouet" ) a 4 arguments positionnels) et nommés (e.g. foo(1, 5, foo="bar", baz="buzz", qux=18 a 2 arguments positionnels et 3 arguments nommés) n'ayant pas été spécifiés explicitement dans la signature de la fonction (e.g. def foo(a, b, c, *args) définit 3 arguments positionnels, et un catchall pour le reste des arguments, donc je dois lui donner au moins 3 arguments et tous les arguments supplémentaires irons dans une list args)
 
Limitations:

  • *args doit impérativement être après tous les arguments positionnels et explicites et ne peut pas être suivi d'arguments nommés explicites, mais il peut être suivi d'un **kwargs. Celà veut dire qu'on peut utiliser des arguments nommés explicites avec *args, mais mieux vaut les considérer comme des arguments positionnels avec une valeur par défaut sous peine d'avoir des surprises
  • **kwargs doit impérativement être après tous les arguments positionnels et tous les arguments nommés (arguments avec une valeur par défaut), c'est obligatoirement le tout dernier argument d'une fonction.


Valides:

Code :
  1. def foo(a, b, c):
  2.    pass
  3.  
  4. def foo(a, b, c, *args):
  5.    pass
  6.  
  7. def foo(a, b, c, **kwargs):
  8.    pass
  9.  
  10. def foo(a, b, c, *args, **kwargs):
  11.    pass
  12.  
  13. def foo(a, b, c, d=5, e="pouet", *args):
  14.    pass
  15.  
  16. def foo(a, b, c, d=5, e="pouet", **kwargs):
  17.    pass
  18.  
  19. def foo(a, b, c, d=5, e="pouet", *args, **kwargs):
  20.    pass


à noter que le dernier et l'avant-avant dernier peuvent avoir des comportements déroutants
 
invalides:

Code :
  1. def foo(*args, a, b, c):
  2.    pass
  3.  
  4. def foo(a, b, c, **kwargs, d):
  5.    pass
  6.  
  7. def foo(a, b, c, **kwargs, d=5):
  8.    pass
  9.  
  10. def foo(a, b, c, *args, d=5):
  11.    pass
  12.  
  13. def foo(a, b, c, **kwargs, *args):
  14.    pass


probablement d'autres.
 
Si tu veux bricoler un peu pour voir comment ça marche, je te conseille d'utiliser ces fonctions là:

Code :
  1. def f(a, b, c, *args, **kwargs):
  2.    print locals()
  3.  
  4. def g(a, b, c, d="d", e="e", *args, **kwargs):
  5.    print locals()


pour voir comment les arguments fournis mappent à args et kwargs


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 20-08-2007 à 22:26:50    

j'ai hate que le livre "Object-Oriented Programming in Python" sorte, j'en ai grand besoin :D merci les gars

Reply

Marsh Posté le 20-08-2007 à 22:54:18    

Commences déjà par "Diving in Python" :)

 

Et il n'y a pas vraiment de "object-oriented in python", si tu connais les concepts fondamentaux de la POO tu pourras les appliquer à Python, après ce qui manque ce sont les idiômes (nb: "La POO en Java" et "La POO en PHP", ce ne sont pas "les conceptes fondamentaux de la POO)

 

En autres lectures intéressantes, je recommande http://dirtsimple.org/2004/12/python-is-not-java.html et le Zen of Python ("import this" dans un shell python)

Message cité 1 fois
Message édité par masklinn le 20-08-2007 à 22:57:21

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 21-08-2007 à 19:37:44    

ben oui justement le probleme est que les cours/livres de POO sont souvent illustres par du C++ ou du java
etant un debutant voire meme bricoleur du dimanche a l'arrachee j'aimerais bien avoir un livre sur la POO qui explique bien les notions de la  POO sans en faire juste une intro,  
 
HS:
la chose que je comprend pas pour java c'est comment on en est arrivee a une telle utilisation en entreprise, a cause de la politique de sun ?
parce que entre java et python : java n'a aucun avantage a mes yeux si ce n'est la notoriete + intergration native dans eclipse (log qui n'existait pas il y a 10 ans)
 
cependant si vous vous connaissez de bons bouquains sur la POO illustre en  code java je reste preneur

Message cité 1 fois
Message édité par flashball le 21-08-2007 à 19:42:21
Reply

Marsh Posté le 21-08-2007 à 20:39:38    

flashball a écrit :

ben oui justement le probleme est que les cours/livres de POO sont souvent illustres par du C++ ou du java


Je t'ai déjà donné Dive, qui est un très bon bouquin sur Python (mais pas sur la prog en général), et gratuit

flashball a écrit :

la chose que je comprend pas pour java c'est comment on en est arrivee a une telle utilisation en entreprise, a cause de la politique de sun ?


marketting (il a été poussé très très fort par e.g. Sun et IBM et présenté très rapidement comme une solution miracle) + ressemblance au "langage entreprise" l'ayant directement précédé (le C++) facilitant les transferts de la masse (qui n'utilisait pas correctement ou pas du tout les fonctionalités du C++ retirée de Java, et n'a donc rien perdu)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 21-08-2007 à 21:24:19    

masklinn a écrit :


Nope.
 
Dans les listes d'arguments python a deux marqueurs magiques, * et ** (habituellement utilisés avec les noms args et kwargs, respectivement, donc *args ou **kwargs, ce n'est néamoins qu'une convention).
 
Leurs rôles sont respectivement de récupérer les attributs positionnels (args) non spécifiés et les arguments nommés (kwargs, ou KeyWord ARGumentS) non spécifiés.
 
Ils servent de catchall pour respectivement les arguments positionnels (e.g. foo(1, 5, "bleh", "pouet" ) a 4 arguments positionnels) et nommés (e.g. foo(1, 5, foo="bar", baz="buzz", qux=18 a 2 arguments positionnels et 3 arguments nommés) n'ayant pas été spécifiés explicitement dans la signature de la fonction (e.g. def foo(a, b, c, *args) définit 3 arguments positionnels, et un catchall pour le reste des arguments, donc je dois lui donner au moins 3 arguments et tous les arguments supplémentaires irons dans une list args)
 
Limitations:

  • *args doit impérativement être après tous les arguments positionnels et explicites et ne peut pas être suivi d'arguments nommés explicites, mais il peut être suivi d'un **kwargs. Celà veut dire qu'on peut utiliser des arguments nommés explicites avec *args, mais mieux vaut les considérer comme des arguments positionnels avec une valeur par défaut sous peine d'avoir des surprises
  • **kwargs doit impérativement être après tous les arguments positionnels et tous les arguments nommés (arguments avec une valeur par défaut), c'est obligatoirement le tout dernier argument d'une fonction.


Valides:

Code :
  1. def foo(a, b, c):
  2.    pass
  3.  
  4. def foo(a, b, c, *args):
  5.    pass
  6.  
  7. def foo(a, b, c, **kwargs):
  8.    pass
  9.  
  10. def foo(a, b, c, *args, **kwargs):
  11.    pass
  12.  
  13. def foo(a, b, c, d=5, e="pouet", *args):
  14.    pass
  15.  
  16. def foo(a, b, c, d=5, e="pouet", **kwargs):
  17.    pass
  18.  
  19. def foo(a, b, c, d=5, e="pouet", *args, **kwargs):
  20.    pass


à noter que le dernier et l'avant-avant dernier peuvent avoir des comportements déroutants
 
invalides:

Code :
  1. def foo(*args, a, b, c):
  2.    pass
  3.  
  4. def foo(a, b, c, **kwargs, d):
  5.    pass
  6.  
  7. def foo(a, b, c, **kwargs, d=5):
  8.    pass
  9.  
  10. def foo(a, b, c, *args, d=5):
  11.    pass
  12.  
  13. def foo(a, b, c, **kwargs, *args):
  14.    pass


probablement d'autres.
 
Si tu veux bricoler un peu pour voir comment ça marche, je te conseille d'utiliser ces fonctions là:

Code :
  1. def f(a, b, c, *args, **kwargs):
  2.    print locals()
  3.  
  4. def g(a, b, c, d="d", e="e", *args, **kwargs):
  5.    print locals()


pour voir comment les arguments fournis mappent à args et kwargs


 
Compris. Si je devais faire une sale analogie, je parlerais de va_args en C.
*args contient une liste d'arguments positionnels (vus de par leur ordre dans les parenthèses) => on peut parler de tableau
**kwargs contient une liste d'arguments nommés (vus par le nom qu'on leur donne) => ici on verrait bien un dictionnaire
ex:

Code :
  1. def toto(*args):
  2.    truc
  3.  
  4. toto(x, y, z) => args[0]=x, args[1]=y et args[2]=z
  5.  
  6. def titi(**kwargs):
  7.    truc
  8.  
  9. titi(nom=x, prenom=y, age=z) => kwargs[nom]=x, kwargs[prenom]=y et kwargs[age]=z


 

masklinn a écrit :

Commences déjà par "Diving in Python" :)


Moi j'ai commencé par le cours de Swinnen http://www.cifen.ulg.ac.be/inforef [...] _notes.pdf que j'ai trouvé remarquablement bien fait. j'ai aussi téléchargé DiveIntoPython (conseillé par Harkonnen) mais j'ai pas eu l'occasion de m'y plonger en détails...

Message cité 1 fois
Message édité par Sve@r le 21-08-2007 à 21:27:06

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-08-2007 à 21:24:19   

Reply

Marsh Posté le 21-08-2007 à 21:35:05    

Sve@r a écrit :


 
Compris. Si je devais faire une sale analogie, je parlerais de va_args en C.


C'est exactement va_args (en un peu plus flexible ptet, et uniquement pour *args, me semble pas qu'il y ait des arguments nommés avec va_args si?)

Sve@r a écrit :

*args contient une liste d'arguments positionnels (vus de par leur ordre dans les parenthèses) => on peut parler de tableau
**kwargs contient une liste d'arguments nommés (vus par le nom qu'on leur donne) => ici on verrait bien un dictionnaire


Non seulement on peut en parler, mais ils sont exactement ça, respectivement un objet de type tuple (une liste immutable) et un objet de type dict ;)

Code :
  1. >>> def f(*args, **kwargs):
  2.     print type(args), type(kwargs)
  3.  
  4.     
  5. >>> f()
  6. <type 'tuple'> <type 'dict'>
  7. >>>


 
Accessoirement, pour les théories POO toussa, je recommande fortement le wiki c2, il y a plein de trucs intéressants dessus: http://c2.com/cgi/wiki?ObjectOriented & http://c2.com/cgi/wiki?FindPage (gaffe par contre, les fonctions de recherches sont pourries :o)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 21-08-2007 à 23:12:03    

masklinn a écrit :


C'est exactement va_args (en un peu plus flexible ptet, et uniquement pour *args, me semble pas qu'il y ait des arguments nommés avec va_args si?)


Non. Le C est assez bas niveau et ne permet pas la création de dictionnaires.
 
Rhaaa plus je découvre Python plus je l'apprécie...

Message cité 1 fois
Message édité par Sve@r le 21-08-2007 à 23:12:33

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-08-2007 à 23:59:45    

Sve@r a écrit :


Non. Le C est assez bas niveau et ne permet pas la création de dictionnaires.
 
Rhaaa plus je découvre Python plus je l'apprécie...


 
Essaye de faire un truc threadé correct en python avec une gui, ça reste le seul truc pour lequel je préfère encore du C ou du C++ :/


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 22-08-2007 à 00:22:23    

0x90 a écrit :


 
Essaye de faire un truc threadé correct en python avec une gui, ça reste le seul truc pour lequel je préfère encore du C ou du C++ :/


En ne communicant qu'avec des queues (Queue.Queue), ça passe :o
 
Mais la méthode conseillée en python ça reste multiprocessus + pipes en fait (guido ne supporte pas les threads, c'est d'ailleurs une des raison pour laquelle il n'a pas envie de s'emmerder à chercher comment faire sauter le gil) [:pingouino]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-08-2007 à 00:25:53    

masklinn a écrit :


En ne communicant qu'avec des queues (Queue.Queue), ça passe :o


Sauf que les tk graphiques sont pas pensés comme ça, donc tu l'as dans le baab.

masklinn a écrit :


Mais la méthode conseillée en python ça reste multiprocessus + pipes en fait (guido ne supporte pas les threads, c'est d'ailleurs une des raison pour laquelle il n'a pas envie de s'emmerder à chercher comment faire sauter le gil) [:pingouino]


Pas con, j'ai jamais testé en pipes, 'fin ça faut du bordel aussi et faut pas vouloir de l'hyper-réactif :/
 
( ou si t'as un insert 3D au milieu par exemple, ça risque d'être un peu lourd de répartir la tâche.... )


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 22-08-2007 à 00:26:30    

0x90 a écrit :


Sauf que les tk graphiques sont pas pensés comme ça, donc tu l'as dans le baab.


:D

0x90 a écrit :


Pas con, j'ai jamais testé en pipes, 'fin ça faut du bordel aussi et faut pas vouloir de l'hyper-réactif :/

 

( ou si t'as un insert 3D au milieu par exemple, ça risque d'être un peu lourd de répartir la tâche.... )


:D
(accessoirement, les pipes toussa c'est devenu vachement plus facile depuis l'arrivée de subprocess, c'est vachement plus simple et cohérent que les os.Popen


Message édité par masklinn le 22-08-2007 à 00:27:33

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-08-2007 à 13:18:22    

python stackless powaaa ???

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed