2016-06-27 20 views
0

Lets sagen, dass ich 2 Klasse haben, und ich möchte die zweiten Klassen in den First-Class-Attribute kann ich so machen:Summe zwei verschiedene Klassenattribute

class first: 
    def __init__(self): 
     self.value_one = 2 
     self.value_two = 5 
     self.value_third = 7 #second class don't have that attribute 

    def sum_class(self, cls): 
     for attribute in cls.__dict__: 
      x = getattr(cls, attribute) 
      y = getattr(self, attribute) 
      setattr(self, attribute, x+y) 


class second: 
    def __init__(self): 
     self.value_one = 3 
     self.value_two = 1 

Aber es sieht nicht pythonic ist es besser Weg, es zu tun?

Meine Klassen werden mehr als 10 Attributen, so will ich nicht eins nach dem anderen hinzufügen, die leicht sein könnte, aber massig Code wie:

def sum(self, cls): 
    self.value_one += cls.value_one 
    self.value_two += cls.value_two 

Auch kann meine dritte Klasse:

class ClassB: 
    def __init__(self): 
     self.value_one = 2 
     self.value_third = 3 

ich möchte auch in der Lage, diese Klasse in meine erste Klasse kann

+0

Mögliches Duplikat von [Wie würde ich auf Variablen von einer Klasse zur anderen zugreifen?] (Http://stackoverflow.com/questions/19993795/how-would-i-access-variables-from-one-class-to- ein anderes) – user2925795

+0

Die einfache Lösung ist, eine allgemeine Basisklasse zu haben, die diese zwei Attribute zur Verfügung stellt und "zuerst" als eine Unterklasse hat, die ein neues Attribut hinzufügt.Im Grunde machen Sie 'second' eine Elternklasse von' first' und verschieben Sie die 'sum_class' Methode auf' second'. Ohne ein konkreteres Beispiel ist nicht klar, ob diese Lösung sinnvoll ist oder nicht. – Bakuriu

+0

@ user2925795 Ich suche tatsächlich nach Art von KlasseA .__ dict__ + classB .__ dict__ es ist anders als Sie senden. Es addiert nur einige Attribute Ich möchte alle hinzufügen – ihsancemil

Antwort

1

die einzige Klasse, die eine behvaiour ähnlich zu dem, was Sie suchen, ist die Counter Klasse:

>>> c = Counter() 
>>> c['a'] = 1.0 
>>> c + Counter('a') 
Counter({'a': 2.0}) 

So könnten Sie speichern diese „Attribute“ innerhalb eines Counter und verwenden __getattr__ normalen Attribut Zugriff zu verwenden:

from collections import Counter 


class ClassWithCounter: 
    def __init__(self, **kwargs): 
     self.counter = Counter(kwargs) 

    def __getattr__(self, attr): 
     # this allows to use the syntax: first().value_one 
     try: 
      return self.counter[attr] 
     except KeyError: 
      raise AttributeError(attr) 

class first(ClasswithCounter): 
    def __init__(self): 
     super(first, self).__init__(value_one=2, value_two=5, value_third=7) 


    def sum_class(self, cls): 
     self.counter += cls.counter 


class second(ClassWithCounter): 
    def __init__(self): 
     super(second, self).__init__(value_one=3, value_two=1) 

ist jedoch zu beachten, dass der Zweck Counter nur zu Zählung Dinge, so kann es einige Situationen geben, in denen es Ihnen seltsame Ergebnisse gibt.

Wenn das der Fall ist, können Sie einfach Ihre eigene Wörterbuch-ähnliche Klasse implementieren und sie anstelle von Counter verwenden.


Auch ein Vorschlag: gegeben, dass Sie dies für ein Spiel schreiben, sollten Sie prüfen, ob diese Art von Update gut ist oder nicht. Denn auf diese Weise gehen die ursprünglichen "Grundwerte" für den Spieler verloren.

Ich persönlich würde die "Basiswerte" getrennt halten und die "Modifikatoren" auf solche Werte aufzeichnen (z. B. Boni oder Malus durch Gegenstände oder temporäre Effekte). Dieser Befehl erlaubt dir, Dinge wie "der Schaden dieses Zaubers wird nicht durch Bonusrüstung beeinflusst" zu implementieren (also benutze einfach den Basiswert, wenn du den Schaden berechnet hast). Ihr aktueller Ansatz macht dies umständlicher.

-1

Sie es kürzer, indem Sie machen hinzuzufügen:

def sum_class(self, cls): 
    [setattr(self, attr, getattr(cls, attr) + getattr(self, attr)) for attr in cls.__dict__] 

Edit 1:

Es war unklar, was Sie wollten, aber nachdem Sie traurig in den Kommentaren Sie so etwas wie classA.__dict__ + classB.__dict_ wollen, vielleicht können Sie diese verwenden:

class sum_class: 
    def __init__(self, class_1, class_2): 
     self.sum = class_1.__class__() 
     self.class_2 = class_2 
     for attr in self.class_2.__dict__: 
      if attr in self.sum.__dict__: 
       setattr(self.sum, attr, getattr(self.class_2, attr) + getattr(self.sum, attr)) 
      else: 
       setattr(self.sum, attr, getattr(self.class_2, attr)) 

class first: 
    def __init__(self): 
     self.value_one = 2 
     self.value_two = 5 
     self.value_third = 7 #second class don't have that attribute 

    def __add__(self, cls): 
     return sum_class(self, cls).sum 

class second: 
    def __init__(self): 
     self.value_one = 3 
     self.value_two = 1 

    def __add__(self, cls): 
     return sum_class(self, cls).sum 

wenn Klassen sind so definiert dann können Sie es wie folgt verwenden:

>>> f = first() 
>>> s = second() 
>>> x = f + s 
>>> x.value_one 
5 
>>> x.value_two 
6 
>>> x.value_third 
7 
+0

wäre es schön zu wissen, was falsch mit meiner Antwort ist – ands

Verwandte Themen