3

I have a class Particle which has some parameters and attributes, as you can see below. But, when it does get to the function setter for position, and it executes the copy() function, I get the error message : RuntimeError: maximum recursion depth exceeded while calling a Python object. I've tried different options, like deepcopy(), or import sys sys.setrecursionlimit(10000) , but none of them worked... Does anyone have any idea? This is my code:

def initCost(n):
    a = random.randint(0,10)              #gram.
    b = random.randint(0,5)             #price
    return [random.randint(0,a*b) for i in range(n)]

costs = initCost(10)

class Particle:
    def __init__(self, n, maxWeight):
        self.position = [random.randint(0,1) for i in range(n)]  #position
        self.velocity = [0 for i in range(n)]                    #velocity
        #self.fit = self.fitness(self.position)
        self.bp = self.position.copy()                           #best position
        self.bf = self.fit                                 #best fitness
        self.evaluate()

    def fit(self, x):
        fitt = 0
        for i in range(len(x)-1):
            if (x[i] == 1):
                fitt = fitt + costs[i]
        return fitt

    def evaluate(self):
        """ evaluates the particle """
        self.fitness = self.fit(self.position)

    @property
    def position(self):
        return self.position

    @property
    def bp(self):
        return self.bp

    @property
    def bf(self):
        return self.bf

    @position.setter
    def position(self, newPosition):
        self.position = newPosition.copy()
        #self.position = newPosition[:]
        self.evaluate()
        # automatic update of particle's memory
        if (self.fit<self.bf):
            self.bp = self.position
            self.bf  = self.fit
5
  • I'm not 100% familiar with Python's version of getters and setters, but I can tell you that the ones in your program are never called because the first thing you do when you instantiate an object of this class is to bind the self.position reference to a list. Commented Apr 13, 2016 at 21:52
  • @TigerhawkT3: No, they're called, and called again, and again... Commented Apr 13, 2016 at 21:53
  • @user2357112: cant you please tell me the mistake I'm making? Commented Apr 13, 2016 at 21:55
  • @user2357112 - Is there something about using properties with setters that prevents them from being masked by identical references? Commented Apr 13, 2016 at 21:55
  • @TigerhawkT3: The "identical reference" goes through the setter. Commented Apr 13, 2016 at 21:55

1 Answer 1

4

It looks like you're trying to use position as the name of both the property and the ordinary attribute backing it. For example,

@position.setter
def position(self, newPosition):
    self.position = newPosition.copy()
#   ^^^^^^^^^^^^^^^

This attempt to set self.position will use the setter you're defining! Similarly,

@property
def position(self):
    return self.position

This getter just calls itself!

Trying to use self.position inside the position property definition won't bypass the property. If you want a "regular" attribute backing the property, call it something else, like self._position or something.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.