-2

What is a good way to avoid duplication of a class instance when it is created using the __init__() function. This question is a result of this issue.

Context (using employee class example):

  1. Lets say I have an employee class: __init__(self,name,dept)
  2. I also have a method, employee.info(self) that prints out name and dept of any employee.
  3. However a user could just add an employee by calling a=employee(args..). They could do it multiple times using the same instance variable a, but different employee names.
  4. This will cause issues if they try to print a.info(), as each time a different employee name will be printed.

Is there a better way to do this? I know it is possible to have the __init__() "pass" and define a new method to create an instance.

Expect results:

>>Adam=employee('marketing')
>>Adam.info()
>>Adam works in marketing.

OR

>>a=employee('Adam','marketing')
>>a=employee('Mary','marketing')
>>Error: employee instance with identifier "a" already exists. 
>>Use employee.update() method to modify existing record.

Is there a cleaner way of doing it? (as you might guess, I am still learning python). Or is it good practice to write an explicit function (instead of a class method) to add new employees?

NVAR
  • 25
  • 7
  • Why do you want this though? Why don't you want to let python override the variable or just add defaults to your class? – Error - Syntactical Remorse Apr 14 '19 at 17:55
  • Because then the info() method is not useful. And the __init__() method the way I use it (to create a new instance) is also not useful because I need to avoid duplicate entry by using a function. What I am trying to do is to avoid duplicate entries. – NVAR Apr 14 '19 at 22:33
  • Wait so you want to use the variable name in the constructor of the class? You are doing something wrong but I can't figure out which aspect your don't understand.. – Error - Syntactical Remorse Apr 14 '19 at 22:34
  • @Error - Syntactical Remorse Yes, I figured I was doing something wrong (and stupid), but probably efficient. My goal is to create a database. Instead of a function to add an element I decided to use __init__() method of the class. Since other methods are called based on the name of the variable (class instance), this approach makes it important to catch possible duplication. If a database entry HAS to be edited, there is specific "update" method which I want to use. But stepping back and looking at it, I am forcing python to make a variable not re-assignable outside of a class method. – NVAR Apr 15 '19 at 13:36
  • Doing this would not be efficient as it requires you to scan all existing variables for the values they contain, then do some logic to error out if that variable is an employee. A programmer should not create objects the way you do in example 2. If you want to create several objects you should do it in a loop and append it to a `list` or `set`. – Error - Syntactical Remorse Apr 15 '19 at 13:42
  • @Error - Syntactical Remorse Thanks. I created class method which tracks objects via a dictionary after seeing your first comment and doing a bit more research- this seems reasonable as I saw it in another thread here. I personally avoid creating objects like example2 but the module could be used by others (who like me aren't programmers either). So trying to make it foolproof. Thanks very much for the inputs. – NVAR Apr 15 '19 at 13:49
  • Be careful. You may end upsetting your users. What if I did `for _ in range(5):` --- `a = Employee()` --- `myList.append(a)` – Error - Syntactical Remorse Apr 15 '19 at 13:59
  • Thanks I am doing this now. Later, I will have to take userinput though. – NVAR Apr 17 '19 at 01:24

2 Answers2

0

what you try is impossible, because in

a=employee('Adam','marketing')

a is not an object but a variable that points to the object employee('Adam','marketing').

When you do

a=employee('Mary','marketing')

you say to python that now, a must now not point to the object employee('Adam','marketing') but to the object employee('Mary','marketing'). And then, if you have no more variable to reference the object employee('Adam','marketing'), the garbage collector will destroy it.

You must consider that in python all is object, but not the variables that are only references to manipulate objects.

Robert
  • 1
  • 1
0

I have been racking my brains over the same problem and have finally managed to figure out a workaround :

  1. Create a dictionary that stores the employee name and the related object like this : total_emp_dict = {}

  2. Add this inside the def __init__ of the class employee : total_emp_dict[name] = self. This will ensure to add each employee name as key and the object associated will be added as value.

  3. Now create a new function outside & before the employee class is defined, let's call it create_new_emp. It will go like this :

    #function to check and avoid duplicate assignment of instances

     def create_new_emp(name, dept):
          if name in total_emp_dict:
             return total_emp_dict[name]
          else:
             return employee(name, dept)
    
  4. When creating a any new employee, use this new function : a = create_new_emp("Adam", HR) instead of a = employee("Adam", HR)

Explanation : This function will ensure that duplicate assignment is not done. If "a" is already assigned to "Adam", this function will return object of "Adam" to "a", when called again. But if nothing is assigned to "a", then this function will handover to the attributes (name, dept) to employee class and create a new instance. This instance will then be assigned to "a".

I don't know if this is the best solution for this problem, but honestly this is the only solution I have found so far and it works great for me without much fuss / extra code space. Hope it works for you too! :)