【问题标题】:Python 3 method to flip arguments in an addition operation在加法运算中翻转参数的 Python 3 方法
【发布时间】:2017-11-25 02:21:42
【问题描述】:

我有一个添加两个点的类(其中一个是 Point 类型,另一个是元组或列表——参见代码)。我的问题是我的 add 方法只有在我按特定顺序输入数字时才有效。我需要创建第二个方法(根据此作业中的规则),它只包含一行调用 add 方法并返回结果,并且可以在文档的数据模型中找到。 p>

class Point():
def __init__(self, x=0, y=0):
    self.x = x
    self.y = y

def __str__(self):
    return ("X = " + str(self.x) + "\nY = " + str(self.y))

def __add__(self, other):
    if isinstance(other,list) or isinstance(other,tuple):
        newX = other[0] + self.x
        newY = other[1] + self.y
        return(Point(newX,newY))
    else:
        newX = self.x + other
        newY = self.y + other
        return(Point(newX,newY))

p = Point(5,10)
print(p + [3.5,6])
print([3.5,6] + p)

我已经搜索了数据模型,我只能认为 reversed 或带有 getattr 的东西会起作用,但我不知道如何实现,或者如果我什至在正确的轨道上。请帮忙!

【问题讨论】:

    标签: python-3.x add reverse datamodel


    【解决方案1】:

    你应该在你的班级中添加__radd__()

    def __radd__(self, *args, **kwargs):
        return self.__add__(*args, **kwargs)
    

    这实际上会执行__add__(),因为在这种情况下它确实是一样的。

    但你可以考虑让这个类表现得像一个列表,像这样:

    class Point():
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
            self._list = [self.x, self.y]
    
        def __str__(self):
            return ("X = " + str(self.x) + "\nY = " + str(self.y))
    
        def __repr__(self):
            return str(self._list)
    
        def __iter__(self):
            for elem in self._list:
                yield elem
    
        def __getitem__(self, i):
            return self._list(i)
    
        def __len__(self):
            return len(self._list)
    
        def __delitem__(self, i):
            #not sure if you really want this
            del self._list[i]
    
        def __setitem__(self, i, val):
            #not sure if you really want this
            self._list[i] = val    
    
        def __add__(self, other):
            #this code could be optimized
            #using your original code for this example
            if isinstance(other,list) or isinstance(other,tuple):
                newX = other[0] + self.x
                newY = other[1] + self.y
            else:
                newX = self.x + other
                newY = self.y + other
            #returning a list
            return [newX, newY]
    
        def __radd__(self, *args, **kwargs):
            return self.__add__(*args, **kwargs)
    
    
    p = Point(5,10)
    print(p)
    print(p + [3.5,6])
    print([3.5,6] + p)
    

    输出:

    [5, 10]
    [8.5, 16]
    [8.5, 16]
    

    [编辑] 如果你决定让它表现得像 list,你也可以继承 list,例如:

    class Point(list):
    
        def __init__(self, x=0, y=0):
            super(Point, self).__init__([x, y])
    
        def __add__(self, other):
            if isinstance(other, (list, tuple)):
                return [sum(i) for i in zip(self, other)]
            elif isinstance(other, (int, float)):
                return [i + other for i in self]
            else:
                return self
    
        def __radd__(self, *args, **kwargs):
            return self.__add__(*args, **kwargs)
    
        #you probably want a __sub__
        def __sub__(self, other):
            if isinstance(other, (list, tuple)):
                return [i - j for i, j in zip(self, other)]
            elif isinstance(other, (int, float)):
                return [i - other for i in self]
            else:
                return self
    
        #and an __rsub__
        def __rsub__(self, other):
            if isinstance(other, (list, tuple)):
                return [i - j for i, j in zip(other, self)]
            elif isinstance(other, (int, float)):
                return [other - i for i in self]
            else:
                return self   
    
        #take away functions you do not want
        def pop(*args, **kwargs): pass
        def sort(*args, **kwargs): pass
        def append(*args, **kwargs): pass
        def extend(*args, **kwargs): pass
        def insert(*args, **kwargs): pass
        def remove(*args, **kwargs): pass
        def reverse(*args, **kwargs): pass
    
    p = Point(5,10)
    tests = [[3.5, 6], (5,4), 1.1, 'wrong string', [1, 2, 3]]
    for test in tests:
        print(p + test)
        print(test + p)
    for test in tests:
        print(p - test)
        print(test - p)   
    p.append(4)
    print(p)
    

    输出:

    [8.5, 16]
    [8.5, 16]
    [10, 14]
    [10, 14]
    [6.1, 11.1]
    [6.1, 11.1]
    [5, 10]
    [5, 10]
    [6, 12]
    [6, 12]
    [1.5, 4]
    [-1.5, -4]
    [0, 6]
    [0, -6]
    [3.9, 8.9]
    [-3.9, -8.9]
    [5, 10]
    [5, 10]
    [4, 8]
    [-4, -8]
    [5, 10]
    

    【讨论】:

    • 我显然没有很好地阅读文档。感谢您的帮助!
    • @vandy,我用子类列表的示例更新了答案,这使得代码更易于管理
    猜你喜欢
    • 2017-03-23
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    相关资源
    最近更新 更多