Yannik
Yannik

Reputation: 1037

Python List Bug in a for loop

I'm not sure how to describe the issue but I'll try it.

Background info

I have in my Django web application a function where the user can import other users. The user can via drag and drop import a .csv file which gets converted to a JSON 2D Array (with Papaparse JS)

In the view, I loop through the elements in the 2D array and create an "Importuser" which contains some properties like "firstname", "lastname", email and so on.

class Importuser:
   firstname = None
   lastname = None
   email = None
   import_errors = []
   def __init__(self, fn, ln, e):
      self.firstname = fn
      self.lastname = ln
      self.email = e

class Importerror:
   message = None
   type = None
   def __init__(self, m, t):
      self.message = m
      self.type = t

In the for-loop, I also validate the email-address, so that there are no doubled users.

data = jsonpickle.decode(method.POST["users"])
users = []
for tempuser in data:
   u = validate(Importuser(tempuser[0], tempuser[1], tempuser[2])
   users.append(u)

In the validate function I check if there any user with the same email

def validate(user : Importuser):
   user_from_db = User.objects.filter(email=user.email)
   if user_from_db:
      user.import_errors.append(Importerror("The user exists already!", "doubleuser"))
   return user

Issue

After the for-loop finished all user have the same error but not when I print each user while doing the for-loop. The Importerror-Object in each user refers to the same memory location but in my test import should only have one user an error.

test.csv:

Dave,Somename,[email protected]
Joe,Somename2,[email protected]
Yannik,Somename3,[email protected] <<That's me (exsiting user)

What I'm doing wrong? can someone help me to understand why this happens?

Upvotes: 0

Views: 202

Answers (2)

AKX
AKX

Reputation: 169154

You've defined import_errors as a class-level static, so it's shared between all instances of Importuser.

See: Static class variables in Python

For your particular problem, rewrite your classes as

class Importuser:
   def __init__(self, firstname, lastname, email):
      self.firstname = firstname
      self.lastname = lastname
      self.email = email
      self.import_errors = []

class Importerror:
   def __init__(self, message, type):
      self.message = message
      self.type = type

Upvotes: 1

user2722968
user2722968

Reputation: 16515

import_errors is a class-attribute of ImportUser. It should be a instance-attribute:

class Importuser:

   def __init__(self, fn, ln, e):
      self.firstname = fn
      self.lastname = ln
      self.email = e
      self.import_errors = []

Upvotes: 0

Related Questions