0

I'm making my first program in Python. I need to add objects to a list, and I create these objects inside a FOR loop. The problem is, after filling the list, if I check the value of any object, they all look like the last object added.

class clsNumeros:

    numero = 4
    oper = [int() for i in range(5)]

    def __init__(self, op1, op2, op3, op4):
        self.oper[1] = op1
        self.oper[2] = op2
        self.oper[3] = op3
        self.oper[4] = op4

    def CountOperaciones():
        return 5

    def GetValorOper(self, idxOper):
        num = self.oper[idxOper]

        if num == 1:
            return num
        elif num == 2:
            return sqrt(num)
        elif num == 3:
            return Factorial(num)
        elif num == 4:
            return 4/10
        elif num == 5:
            return sqrt(0.4)

    def GetExprOper(self, idxOper):
        num = self.oper[idxOper]

        if num == 1:
            return num
        elif num == 2:
            return "R(" + num + ")"
        elif num == 3:
            return num + "!"
        elif num == 4:
            return "0.4"
        elif num == 5:
            return "R(0.4)"

    def Display(self):

        txt = ""

        for x in range(1, 5):
            txt = txt + str(self.oper[x])
            txt = txt + " ___ "

        print (txt)



def GeneraNumeros():
    c = []
    idx = [int() for i in range(5)]
    i = 0
    idx[1] = 1
    idx[2] = 1
    idx[3] = 1
    idx[4] = 1
    looping = 1
    n = 0

    while looping == 1:
        num = clsNumeros(idx[1], idx[2], idx[3], idx[4])
        c.append(num)
        n = n + 1
        idx[4] = idx[4] + 1
        for i in range (4, 1, -1):
            if idx[i] > clsNumeros.CountOperaciones():
                idx[i] = 1
            idx[i-1] = idx[i-1] + 1
        if idx[1] > clsNumeros.CountOperaciones():
            looping = 0

        c[5].Display()  # this is for displaying object number 5. All of them look like the last one

    return numeros        

What could be wrong? Can I create objects inside a FOR loop and expect them to be unique? This idea works fine on ASP.NET.

Thanks!

Corley Brigman
  • 11,633
  • 5
  • 33
  • 40
Alvaro VS
  • 203
  • 1
  • 5
  • 15

1 Answers1

3

The problem is here:

class clsNumeros:

    oper = [int() for i in range(5)]

class variables are evaluated once, at the moment of class definition. Therefore, only one instance of list is created here. Fix that by initialising oper in the constructor instead.

Other issues:

  • you can just say 0 instead of int()
  • you can just say [0]*5 instead of [0 for i in range(5)]
  • naming conventions: Python uses method_name and ClassName, it's good to follow them
  • get the habit of writing class clsNumeros(object), because the other (older) syntax results in an "old-style" class in Python which behaves a bit differently
  • you can simplify the method Display by using the str.join method, for example '__'.join(items)
Kos
  • 70,399
  • 25
  • 169
  • 233
  • Thanks!! Now I understand. Sorry if it looks like a duplicated question, but I though my problem was different. Now I see that class variables should be declared inside the __init__ part. – Alvaro VS Jan 31 '14 at 15:10
  • *Instance* variables should go into `__init__`, while class variables go directly inside the class definition. Also note that for simple immutable objects (numbers, strings) it doesn't make such a big difference: `obj.numero` will access the class variable initially, but `obj.numero += 1` will write into the instance and this one will be picked up next time. – Kos Jan 31 '14 at 15:12