__setitem__ implementation in Python for Point(x,y) class

前端 未结 7 985
故里飘歌
故里飘歌 2020-12-14 12:44

I\'m trying to make a Point class in python. I already have some of the functions, like __ str__ , or __ getitem__ implemented, and it works great. The only problem I\'m fac

相关标签:
7条回答
  • 2020-12-14 13:28

    This works in python 2.6 i guess it works for 2.7 as well

    The __setitem__ method accept 3 arguments (self, index, value)

    in this case we want to use index as int for retrive the name of the coordinate from __slots__ tuple (check the documentation of __slots__ is really usefull for performance)

    remember with __slots__ only x and y attributes are allowed! so:

    p = Point()
    p.x = 2
    print(p.x)  # 2.0
    
    p.z = 4  # AttributeError
    print(p.z)  # AttributeError
    

    This way is faster respect using @property decorator (when you start to have 10000+ instances)

    class Point(object):
        @property
        def x(self):
            return self._data[0]  # where self._data = [x, y]
    ...
    

    so this is my tip for you :)

    class Point(object):
    
        __slots__ = ('x', 'y')  # Coordinates
    
        def __init__(self, x=0, y=0):
            '''
            You can use the constructor in many ways:
            Point() - void arguments
            Point(0, 1) - passing two arguments
            Point(x=0, y=1) - passing keywords arguments
            Point(**{'x': 0, 'y': 1}) - unpacking a dictionary
            Point(*[0, 1]) - unpacking a list or a tuple (or a generic iterable)
            Point(*Point(0, 1)) - copy constructor (unpack the point itself)
            '''
            self.x = x
            self.y = y
    
        def __setattr__(self, attr, value):
            object.__setattr__(self, attr, float(value))
    
        def __getitem__(self, index):
                '''
                p = Point()
                p[0]  # is the same as self.x
                p[1]  # is the same as self.y
                '''
            return self.__getattribute__(self.__slots__[index])
    
        def __setitem__(self, index, value):
                '''
                p = Point()
                p[0] = 1
                p[1] = -1
                print(repr(p))  # <Point (1.000000, -1.000000)>
                '''
            self.__setattr__(self.__slots__[index], value)  # converted to float automatically by __setattr__
    
        def __len__(self):
            '''
            p = Point()
            print(len(p))  # 2
            '''
            return 2
    
        def __iter__(self):
            '''
            allow you to iterate
            p = Point()
            for coord in p:
                print(coord)
    
            for i in range(len(p)):
                print(p[i])
            '''
            return iter([self.x, self.y])
    
        def __str__(self):
            return "(%f, %f)" % (self.x, self.y)
    
        def __repr__(self):
            return "<Point %s>" % self
    
    0 讨论(0)
提交回复
热议问题