#1 Le 05/04/2011, à 19:37
- AnsuzPeorth
[Résolu][python] Héritage via variables
Bjr,
J'y ai passé une paires d'heures, mais je vois pas comment réaliser cela.
Je voudrais importer et hériter de modules non prédéfini, via une variable. J'ai regardé du coté de super() ou des décorateurs, mais je vois vraiment pas !
Le résultat voulu:
from toto import Toto
from momo import Momo
class Myclass(Toto, Momo):
def __init__(self):
Toto.__init__(self)
Momo.__init__(self)
L'idéal, serait de passer par un fichier intermédiaire.
fichier principal:
from module import Mod
class Myclass(Mod):
def __init__(self):
Mod.__init__(self)
module:
class Mod(object):
def __init__(self):
l = { 'toto':'Toto', 'momo','Momo' }
for n in l:
eval( 'from %s import %s' % (n.key, n.value) )
eval( '%s.__ini_(%s)' % (n.value, self) )
Ou alors les paramétres de la classe via une variable
var = 'Momo,Toto'
class Myclass(var):
def __init__(self):
var.__init__(self)
Même si il existe une solution avec un fichier tiers, indiquer des paramètres à une fonction via une variable, m'intéresserai (jamais réussi !)
var='1,2'
fonction(var)
Comme il y a qqles cadors sur ce forum, peut être que l'un d'eux me sauvera la mise !
(ca tombe c'est un truc tout con que je ne connais pas.)
Merci d'avance.
Dernière modification par AnsuzPeorth (Le 07/04/2011, à 12:15)
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#2 Le 05/04/2011, à 22:58
- valAa
Re : [Résolu][python] Héritage via variables
Même si il existe une solution avec un fichier tiers, indiquer des paramètres à une fonction via une variable, m'intéresserai (jamais réussi !)
var='1,2' fonction(var)
Rapidement, en passant.
Il est tout à fait possible de passer une liste (ou un tuple, ou un générateur) à une fonction qui attend une série d'arguments:
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo(a, b):
... return a + b
...
>>> var = '(1,2)'
>>> args = eval(var)
>>> args
(1, 2)
>>> foo(*args)
3
>>>
(ps: la même pour les paramètres passés par nom avec un dico) :
>>> var = "{'b':1, 'a':2}"
>>> kwargs = eval(var)
>>> kwargs
{'a': 2, 'b': 1}
>>> foo(**kwargs)
3
>>>
Dernière modification par valAa (Le 05/04/2011, à 23:06)
Hors ligne
#3 Le 05/04/2011, à 23:26
- AnsuzPeorth
Re : [Résolu][python] Héritage via variables
Merci pour la réponse. Je la note dans un coin de ma tête, ca va me servir
Par contre, ça marche pas avec les classes.
#
class Go(*args):
^
SyntaxError: invalid syntax
EDIT: finalement, le truc du dico nickel
Ca fonctionne avec python, j'essaierai avec pygtk, ca me sera d'un grand secours.
Je pourrait ajouter des arguments et leurs valeurs via un dico.
Pourquoi j'y ai jamais pensé .... ?
Dernière modification par AnsuzPeorth (Le 05/04/2011, à 23:36)
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#4 Le 05/04/2011, à 23:52
- valAa
Re : [Résolu][python] Héritage via variables
Pour tes histoires de classes, regarde du coté des metaclass.
Pas le temps de développer (mais plein de doc sur le web) :
>>> class A(object):
... def __init__(self):
... super(A, self).__init__()
... self.x = 1
...
>>> class B(object):
... def __init__(self):
... super(B, self).__init__()
... self.y = 2
...
>>> inherits = eval("(A,B)")
>>> def C_init(self):
... super(C, self).__init__()
...
>>> C = type('C', inherits, {'__init__': C_init})
>>> C
<class '__main__.C'>
>>> c = C()
>>> c.x
1
>>> c.y
2
>>>
(type est la metaclass de base en python, tup peux te créer une metaclass perso héritant de type si tu veux.).
En gros, en jouant avec les metaclass, tu devrais arriver à tes fins.
Dernière modification par valAa (Le 06/04/2011, à 00:01)
Hors ligne
#5 Le 06/04/2011, à 00:24
- AnsuzPeorth
Re : [Résolu][python] Héritage via variables
Pour tes histoires de classes, regarde du coté des metaclass.
J'y suis depuis un moment, et les metaclass, c'est super() ... super(incompréhensible) ...
J'ai déjà eu un peu de difficulté avec les classes et l'héritage (maintenant je trouve ça hyper simple et logique), mais avec les metaclass, et pis les décorateur aussi ... Je vais y passer un moment.
C'est sur, le net regorge de tuto, pour ceux qui connaissent, c'est simple et clair, mais lorsque tu découvres, c'est souvent de l'hébreu pour des yeux non-averti.
En gros, en jouant avec les metaclass, tu devrais arriver à tes fins.
Comme tu dis, je vais m'amuser
Thx
Dernière modification par AnsuzPeorth (Le 06/04/2011, à 00:31)
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#6 Le 06/04/2011, à 10:43
- valAa
Re : [Résolu][python] Héritage via variables
Une proposition en wrappant la création d 'une metaclass dans une fonction paramétrable :
A, B et C sont trois classes dérivant de object.
make_meta() est une fonction prenant des classes en argument et qui retourne une métaclasse (Meta) qui ajoute les arguments aux parents déjà déclarés de la classe à instancier (c'est clair ? ).
Je crée une classe D qui hérite déjà de A, et qui va hériter aussi dynamiquement de B et de C via sa metaclasse :
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A(object):
... def __init__(self):
... super(A, self).__init__()
... self.x = 0
...
>>> class B(object):
... def __init__(self):
... super(B, self).__init__()
... self.y = 1
...
>>> class C(object):
... def __init__(self):
... super(C, self).__init__()
... self.z = 2
...
>>> def make_meta(*parents):
... class Meta(type):
... def __new__(metacls, name, bases, dct):
... new_bases = tuple(bases) + parents
... return type.__new__(metacls, name, new_bases, dct)
... return Meta
...
>>> other_parents = (B,C)
>>> class D(A):
... __metaclass__ = make_meta(*other_parents)
... def __init__(self):
... super(D, self).__init__()
...
>>> D
<class '__main__.D'>
>>> d = D()
>>> d.x
0
>>> d.y
1
>>> d.z
2
>>>
Dernière modification par valAa (Le 06/04/2011, à 11:34)
Hors ligne
#7 Le 06/04/2011, à 12:45
- AnsuzPeorth
Re : [Résolu][python] Héritage via variables
Génial, c'est exactement ce que je recherchais
J'avais bien compris que la metaclass devait avoir __new__ pour modifier le __init__ de la class 'mère'. Mais j'avais pas réussi à remplir et retourner le dictionnaire.
En tout cas, tes exemples sont bien plus explicitent que ceux que j'ai trouvé sur le net !
Déjà l'exemple de hier m'avait bien éclairé, avec celui d'aujourd'hui, nickel
Y'a pas à dire, rien ne vaut un exemple pour un problème donné (que l'on connait), tous les tutos ne remplaceront jamais l'aide direct d'un tiers.
Un petite explication de super(simple) trouvé: http://www.siteduzero.com/forum-83-2236 … t-cls.html
Le super fait référence à la classe parente : si Bar hérite de Foo, super(Bar) désignera Foo (plus ou moins.).
Une autre petite chose intéressante dans ce contexte: http://www.siteduzero.com/forum-83-4110 … iable.html
module_name = 'os'
module = __import__(module_name)
Bein que eval() fait la même chose, mais c'est bon à savoir.
En tout cas, un grand merci, même si finalement je vais pas utiliser cette méthode. Mais c'est pas du temps de perdu, loin de là. maintenant les metaclass me paraissent moins obscur. Par la même, les décorateurs (c'est le même principe mais pour des fonctions).
Le but à l'origine était de diviser un gros script (2500 lignes), composé de 2 class principales (découpées en plusieurs class héritées).
Je voulais donc importer seulement ceux dont j'avais besoin (modules et fonctions), pour faire la chasse au gaspille de mémoire.
J'ai installé guppy pour voir l'utilisation mémoire de l'appli, et en découpant et utilisant les metaclass, je devrais gagner, pffiiouuu, 500 Ko sur 4 Mo de mémoire utilisé ... Le jeux n'en vaut pas la chandelle (1/8 eme c'est déjà pas mal, mais bon ...). Surtout que l'utilisation principale de la mémoire est l'affichage de l'interface graphique (entre 6 et 10 Mo) . Donc là, ca fait gagner peanuts !
Maintenant, le principe des metaclass permettent d'importer et d'hériter de modules chargés depuis un fichier .ini par exemple, c'est super(), c'est un truc dont j'avais besoin aussi pour autre chose (bien que j'aurais pu contourner facilement dans ce cas précis, mais la solution des metaclass est plus approprié je pense). L'ajout de plugins dynamiquement au script va devenir un jeux d'enfants
Aller, encore un petit merci pour la route, car là tu m'a enlever une grosse épine du pied (j'avais déjà pas mal lu au sujet des meta et decorator, mais je pigais pas grand chose, du à des exemples trop basiques, et des explications trop techniques, maintenant, la notion est compris, faudra l'appliquer par contre, c'est une autre histoire )
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#8 Le 07/04/2011, à 09:25
- AnsuzPeorth
Re : [Résolu][python] Héritage via variables
Bon, ben c'est bien ce que je pensais, la théorie OK, la pratique ....
J'ai une erreur:
TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
j'ai essayé ceci:
class NewClass(object):
def __init__(self):
super(NewClass, self).__init__()
def make_meta(*parents):
class Meta(type):
def __new__(metacls, name, bases, dct):
new_bases = tuple(bases) + parents
return type.__new__(metacls, name, new_bases, dct)
return Meta
class Tampon(object):
def __init__(self):
super(Tampon, self).__init__()
class Commandes(Tampon):
__metaclass__ = make_meta((NewClass,))
def __init__(self):
super(Commandes, self).__init__()
#J'ai une classe qui dérive la class commande, qui hérite déjà de theading, le problème vient peut être de là ?
class MyThread(threading.Thread, Commandes):
def __init__(self, gui):
threading.Thread.__init__(self)
J'ai essayé un peu toutes les solutions, mettre __metaclass__ dans MyThread, dans Tampon, supprimer Tampon .. Rien à faire !
En fin de compte, je veux que la class NewClass ai des fonctions accessible depuis Commande et MyThread (vu qu'elle hérite de Commande)
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#9 Le 07/04/2011, à 11:05
- valAa
Re : [Résolu][python] Héritage via variables
Le problème vient de ta manière de passer l'argument à make_meta().
tu as défini make_meta comme prenant un nombre variable d'arguments `make_meta(*parents)`, qui doivent être des classes.
Or toi tu l'appelles de cette manière :
__metaclass__ = make_meta((NewClass,))
De cette manière, tu lui passe un argument qui est un tuple, donc il essaie de faire hériter ta classe Commandes de `instance de tuple` -> crash
Tu dois appeler make_meta de cette manière
__metaclass__ = make_meta(NewClass)
(tu lui passe bien une classe en argument)
ou bien
__metaclass__ = make_meta(*(NewClass,))
(tu "expand" le tuple pour le transformer en autant d'arguments qui'il a d'élements).
Donc ton problème ne vient pas des metaclass mais d'une mauvaise utilisation du système de nombre variable d'arguments de python.
Après tu n'es pas obligé de l'utiliser, et tu peux définir make_meta() comme prenant un seul argument, de type tuple ou liste.
Dernière modification par valAa (Le 07/04/2011, à 11:22)
Hors ligne
#10 Le 07/04/2011, à 11:28
- AnsuzPeorth
Re : [Résolu][python] Héritage via variables
CA MARCHE
Content Rosko, content.
Un jour j'y arriverai peut être un jour ... à ton niveau
Finalement, je ne connais que les bases en python, j'ai passé tout mon temps à étudier pygtk, et pour appronfondir python, ben faut se lancer dans de gros truc, parceque la théorie sur des petits exemples c'est une chose, la pratique une autre.
En tout cas merci, je vais pouvoir penser mes programmes différemment, metaclass et decorator en avant toute !
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#11 Le 07/04/2011, à 11:36
- valAa
Re : [Résolu][python] Héritage via variables
CA MARCHE
Cool
Finalement, je ne connais que les bases en python, j'ai passé tout mon temps à étudier pygtk, et pour appronfondir python, ben faut se lancer dans de gros truc, parceque la théorie sur des petits exemples c'est une chose, la pratique une autre.
Tu sais, on est là dans des concepts assez avancés de programmation python, c'est donc normal de ne pas les maîtriser en quelques jours.
En tous cas merci aussi pour ta question car ça m'a donné un petit exo pratique de métaprogrammation (et non je ne suis pas un 'cador', je suis aussi (et éternellement j'espère) un type qui apprend, c'est juste que ça commence à faire quelques années que je touche à python).
En tout cas merci, je vais pouvoir penser mes programmes différemment, metaclass et decorator en avant toute !
Attention à ne pas en abuser. Penser aussi à la lisibilité et à la maintenance du code
Dernière modification par valAa (Le 07/04/2011, à 11:37)
Hors ligne
#12 Le 07/04/2011, à 11:53
- AnsuzPeorth
Re : [Résolu][python] Héritage via variables
Tu sais, on est là dans des concepts assez avancés de programmation python, c'est donc normal de ne pas les maîtriser en quelques jours.
Ben disons que tes explications et exemples, m'ont plus appris que les tutos ou doc que j'ai lu sur le net (pourtant j'y ai passer du temps, je ne demande pas d'aide avant d'y avoir passer un paquet d'heures, alors que ca me ferait gagner du temps de demander tout de suite, mais bon, j'apprends d'autres choses en cherchant !)
Je vais pas dire que je maitrise, mais au moins maintenant, je comprends le principe et l'utilité de la chose.
Attention à ne pas en abuser. Penser aussi à la lisibilité et à la maintenance du code
J'ai un nouveau jouet, je vais m'en servir
Je plaisante, de toute façons c'est a utiliser dans des conditions vraiment spécifique, on doit pas en avoir besoin tous les jours !
Sinon après les metaclass et decorator, y a koi de particulier encore à apprendre en python ?
Je ne parle pas des fonctions ou modules spécifiques, mais de choses générales comme celle là, des particularités propre à python, ou plutot, je pense, dépendant de la POO.
Les threads (ok dans les grandes lignes), l'héritage et instances (pffff, trop facile, alors qu'au début ...), les meta et docator (enfin compris), après ...?
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne