10
votes

Python: Comment "fusionner" deux classe

Je veux ajouter des attributs et des méthodes en différentes classes. Les méthodes et attributs que je dois ajouter sont les mêmes mais pas la classe à les assigner, donc je souhaite construire une classe qui attribue de nouvelles méthodes et attributs d'une classe donnée en argument. J'essaie ceci mais ça ne marche pas: (Je sais que c'est une mauvaise façon d'essayer d'assigner quelque chose à soi, il est juste de montrer ce que je veux faire) xxx

Le résultat est le suivant: xxx

Et je m'attendais à avoir "A" pour l'appel de Institut.gettattb ()

Pour reprendre, je veux hériter de la classe B de la classe A de classe A en argument de classe B Parce que ma classe B sera une sous-classe de différentes classes, pas toujours une.


5 commentaires

Je ne comprends pas ce que vous essayez de faire, pourriez-vous fournir un exemple complet avec le résultat attendu? Utilisez classe A (objet) et Classe B (objet) , cependant, au moins si vous envisagez de prendre en charge Python 2.x.


Ça ne fonctionne pas - comment ça ne marche pas?


Veuillez poster la sortie que vous obtenez lorsque vous exécutez le code.


Dans [5]: dir (instb) out [5]: [ __ doc __ , __ init __ , __ module __ , "getattb"] il n'y a pas de getatt Méthode avec l'objet Instb, si vous le souhaitez, vous devez hériter de la classe B de la classe A


Self n'est accessible que dans la méthode __ init __ . Vous devriez utiliser self.elf = parent et faire autoelf.gett ()


7 Réponses :


0
votes

Je ne suis pas certain de ce que vous essayez de faire, mais le code ci-dessous donne ma sortie, je pense que vous attendez. AVIS:

  1. A est initialisé à l'extérieur du constructeur dans un
  2. B est déclaré comme une sous-classe d'un

    code: xxx


6 commentaires

Oui, c'est ce que je veux faire, mais le parent de B n'est pas toujours la classe A et je ne créerais pas de sous-classe pour chaque classe.


Affectation d'une valeur à Self est juste mal et n'échappe pas à la fonction de la fonction de fonction ...


Je ne pense pas qu'il soit possible de définir dynamiquement une classe mère. Le parent doit être déclaré pour que le compilateur puisse trouver les attributs de Superclass. Si B n'est pas déclaré une sous-classe de A , vous ne pourrez pas accéder à a


@ Po'lazarus Je sais cela, mais je voulais lui donner une "solution" à son problème. Je ne sais pas pourquoi il fait ce qu'il fait, alors je ne voulais donc pas lui dire que ce qu'il fait est faux, lui donner un moyen d'obtenir la sortie qu'il veut.


Vous pouvez déclarer de manière dynamique le héritage dans Python. Si vous avez une fonction de constructeur qui reçoit un ou plusieurs arguments de type, vous pouvez les transmettre à taper () et créer un nouveau type sous-classé de ces types au moment de l'exécution.


Eh bien, pour les cas d'utilisation de base, type () est la fonction de constructeur ... FOOISH = TYPE ('FOOISH', (FOO,), {}) Donnera Une variable nommée FOOISH qui est une poignée pour un nouvel objet de type FOOISH qui dérive de FOO et n'a pas de membres personnalisés supplémentaires.



1
votes

Etant donné que B n'est pas une sous-classe d'un, il n'y a pas de chemin dans B de gettat () dans un


0 commentaires

3
votes

Comment de cela?

import functools
class A:
    def __init__(self):
        self.a = 'a'

    def getatt(self):
        return self.a

class B:
    def __init__(self, parent):
        for attr, val in parent.__dict__.iteritems():
            if attr.startswith("__"): continue
            self.__dict__[attr] = val
        for attr, val in parent.__class__.__dict__.iteritems():
            if attr.startswith("__"): continue
            if not callable(val): continue
            self.__dict__[attr] = functools.partial(val, self)

    def getattB(self):
        return self.getatt()

insta = A()
instb = B(insta)

print instb.__dict__
print instb.getattB()
print instb.getatt()


6 commentaires

Oui, je pense que c'est la seule façon de faire ce que je veux. Je vais assigner l'attribut et la méthode à B avec la classe A. Comme (en classe B) auto.a = auto.parent.a et def getatt (auto): retourne self.parent.gett () Je cherche une manière plus rapide mais merci


Cela implémente essentiellement une nouvelle syntaxe pour héritage dynamique, où Python vous donne un pour commencer. insta = a () instb = Tapez ('B', (a,), {}) . Il suffit de déclarer une méthode statique sur la classe B qui prend une longueur arbitraire tuple d'autres classes et des retours de type ([nouveau nom de classe], [tuple de classes, y compris B], [Membres que vous souhaitez ajouter au moment de l'exécution]).


@ SR2222, génial, j'essaie instb = type ("", (objet, b, insta .__ classe__), Insta .__ dict __) () peut faire la même chose fonctionner.


Très bien. Je peux fusionner ma classe avec C = type ('C', (A, B), {}). Et j'ai des méthodes et des attributs d'A et B dans C. (seulement A est initialiser)


@SHOWNS Je ne sais pas à quel point l'utilisation d'une chaîne vide pour votre nom de classe est ... De plus, l'héritage explicite de l'objet est inutile si vous utilisez simplement de nouvelles classes de style pour commencer et avoir A et B hériter de l'objet eux-mêmes. Vous devriez vraiment utiliser de nouvelles classes de style de toute façon ... et Insta .__ dict__ est entièrement superflu aussi, car c'est tout le point de sous-classement en premier lieu ...


@ SR2222, oui si A et B sont de nouvelles classes de style qui seront erronées. Insta .__ dict__ peut importer attrvenez de Insta, si cela n'a pas besoin d'importation, DEF FAITE (base, parent): classe neuve (base, parent): transmettez-la nouvelle .



12
votes

La meilleure réponse est dans les commentaires, c'était utile pour moi, alors j'ai décidé de le montrer dans une réponse (merci à SR2222): Le chemin de Dynamicy déclarer le horizon dans Python est la fonction de type () intégrée. Pour mon exemple: xxx

le code retour: xxx

Mes attributs d'inerhite de classe C et méthodes de classe A et classe B et nous ajoutons Attribut C. Avec l'instanciation de C (inscc = c ('args')), le init d'init pour A est un appel mais non pour b.

très utile pour moi parce que je dois ajouter quelques Attributs et méthodes (la même) sur différentes classes.


1 commentaires

J'ai également rencontré ce problème, et c'est très utile. Pour mon cas, j'avais différentes sous-classes "combinables" d'une classe mère. L'ajout de sous-classes spécifiques est devenue des méthodes de la classe mère.



3
votes

J'avais du mal à appeler différents constructeurs, en utilisant Super code> n'a pas nécessairement de sens dans un cas comme celui-ci, j'ai choisi d'hériter manuellement et appelez chaque constructeur sur l'objet actuel:

class Foo(object):
    def __init__(self, foonum):
        super(Foo, self).__init__()
        self.foonum = foonum


class Bar(object):
    def __init__(self, barnum):
        super(Bar, self).__init__()
        self.barnum = barnum

class DiamondProblem(Foo, Bar):
    # Arg order don't matter, since we call the `__init__`'s ourself.
    def __init__(self, barnum, mynum, foonum):
        Foo.__init__(self, foonum)
        Bar.__init__(self, barnum)

        self.mynum = mynum


0 commentaires

0
votes

Je suppose que j'ai une méthode plus facile xxx


0 commentaires

0
votes

La fonction d'assistant ci-dessous effectue la fusion des instances de données de données, les ordres d'attributs sont dérivés de * args ordre: xxx


0 commentaires