总结两个不同的类属性

时间:2016-06-27 11:39:16

标签: python

假设我有2个类,我想将第二个类属性添加到第一个类我可以这样做:

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

但它有什么更好的方法可以看到pythonic吗?

我的课程将拥有超过10个属性,所以我不想逐个添加,这可能很容易但是大量的代码如下:

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

我的第三堂课也可能有:

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

我还希望能够将这个课程添加到我的第一堂课

2 个答案:

答案 0 :(得分:1)

唯一一个与你正在寻找的类似的类是Counter类:

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

因此,您可以将这些“属性”存储在Counter中,并使用__getattr__来使用普通属性访问权限:

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)

但请注意Counter的目的只是计算事物,所以在某些情况下它可能会给你带来奇怪的结果。

如果是这种情况,您可以简单地实现自己的类字典,并使用它代替Counter

另外一个建议是:鉴于你是为游戏写这个,你应该考虑这种更新是否好。因为以这种方式,玩家的原始“基础价值”会丢失。

我个人会将“基础值”分开并跟踪这些值的“修饰符”(例如由项目提供的奖励或墨水,或临时效果)。 这个apporach允许你实现诸如“此法术的伤害不受额外护甲影响”之类的东西(所以你只需在计算伤害时使用基础值)。您当前的方法使这更加麻烦。

答案 1 :(得分:-1)

您可以使用以下内容缩短时间:

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

编辑1:

目前还不清楚你想要什么,但是在评论中你想要classA.__dict__ + classB.__dict_这样的话后,你可以使用这个:

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

当类被定义为那样时,你可以这样使用它:

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