2
     def __init__(self, unique_id=uuid.uuid4())

I want every object I instantiate to have a different ID if the user doesn't specify one. When I instantiate several classes, they all have the same UUID. May I have a technical overview of what's going on here, so I may better understand Python functions and initializers?

Parity Bit
  • 113
  • 1
  • 12
  • 3
    Default parameters in Python are evaluated at function *definition* time, not function *call* time. They become part of the function object. I'm sure there's a question on SO somewhere about this. – Mark Ransom Aug 09 '17 at 18:29
  • 1
    https://stackoverflow.com/questions/1651154/why-are-default-arguments-evaluated-at-definition-time-in-python – Mark Ransom Aug 09 '17 at 18:31

2 Answers2

2

I believe it makes your code cleaner, if you just add this to the method body, i.e. something like:

def __init__(self, unique_id=None):
    if not unique_id:
        unique_id = uuid.uuid4()

The more compact version of this would be:

def __init__(self, unique_id=None):
    unique_id = uuid.uuid4() if not unique_id else unique_id

This would allow you to overwrite unique_id if required.

m_____z
  • 1,521
  • 13
  • 22
2

The problem with your proposed code is that the default parameter is evaluated only once (when you import the module), see e.g. "Least Astonishment" and the Mutable Default Argument.

In order to fix this, you should follow the idiom of using None as a flag for "not provided by user", like so:

def __init__(self, unique_id=None):
    if unique_id is None:
        unique_id = uuid.uuid4()
Jonas Adler
  • 10,365
  • 5
  • 46
  • 73