0

I am trying to adapt a singleton example from Real Python, and I have simplified the code for clarity.

# employees.py


class _EmployeeDatabase:
    def __init__(self):
        self._employees = {
            1: {
                'name': 'Mary Poppins',
                'role': 'manager'
            },
            2: {
                'name': 'John Smith',
                'role': 'secretary'
            },
            3: {
                'name': 'Kevin Bacon',
                'role': 'sales'
            },
            4: {
                'name': 'Jane Doe',
                'role': 'factory'
            },
            5: {
                'name': 'Robin Williams',
                'role': 'secretary'
            }
        }

    def employees(self):
        return [Employee(id_) for id_ in sorted(self._employees)]

    def get_employee_info(self, employee_id):
        info = self._employees.get(employee_id)
        if not info:
            raise ValueError('invalid employee_id')
        return info


class Employee:
    def __init__(self, id):
        self.id = id
        info = employee_database.get_employee_info(self.id)
        self.name = info.get('name')
        self._role = get_role(info.get('role'))



employee_database = _EmployeeDatabase()

What I want is to replace the content of self._employees with a dictionary I generated from user input (called dict_employees if you will).

What would be the pythonic way to pass dict_employees to class _EmployeeDatabase?

What seem to be preventing me from passing the dictionary to the class are that

  1. If employee_database = _EmployeeDatabase(dict_employees) takes place outside the module employees.py, class Employee loses access to employee_database.
  2. On the other hand, I do not want to naively import the module where dict_employees is generated for various reasons*.

Sorry in case this is a duplicate question but I am not familiar with Python enough to tell.

===========================

* You probably do not need to know but one reason is that dict_employees has already been generated before my program needs the employees.py module. Another reason is that my program is running multiprocessing and importing dict_employees will result in it being generated multiple times which is wasteful.

3
  • What's wrong with adding a dict argument to _EmployeeDatabase.__init__? Commented Aug 18, 2022 at 8:34
  • As explained in my question, I will need this statement: employee_database = _EmployeeDatabase(dict_employees). But where would I put this statement? If it is outside the module employees.py, class Employee loses access to employee_database; if it is left where it currently is, I seem to have to import dict_employees from where it is born which I am trying to avoid for reasons explained at the end of my question. Commented Aug 18, 2022 at 8:40
  • I guess I want to modify the module in a way such that employee_database = _EmployeeDatabase(dict_employees) can be stated outside the module, if this is the right direction of thinking... Commented Aug 18, 2022 at 8:49

1 Answer 1

1

I think one of your issues is that the values for an Employee instance get set upon init rather than at runtime. If you'd like Employee instances to update their data when employee_database is changed, it seems to me that you have two options:

  • implement an update() routine in the Employee class which must be called on each instance when employee_database is updated
  • instead of setting values in Employee.__init__(), use getter routines which look the information up every time.

I'm guessing the second method makes the most sense for your application.

Once that's fixed up, you can technically do the (horrible, horrible)

employees.employee_database._employees = dict_employees

where dict_employees is your input. However, a more Pythonic way would be to create a routine that does this from inside the _EmployeeDatabase class:

    def set_employee_database(self, newdict):
       self._employee_database = newdict

and then run:

employee.employee_database.set_employee_database(newdict)

from outside the employee module.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.