
About
You might be surprised to see this code.
def f_bug(arg, result=[]):
result.append(arg)
print(result)
f_bug('a') # ['a']
f_bug('b') # ['a', 'b']
If you are Python beginner, you would expect the response [‘b’] from second f_bug function calling. But it is NOT. why does it happen?
Why does it happen?
The reason is that default variable (which is argument,) is initialized when the function is defined. So, once it is initialized to set a default value, it will be changed afterwards. Therefore it, it would make engineers confused I believe. The good strategy here is not to use mutable variables such as list, dict set as default, and to use immutable variables such as values (int, float) and tuple so that the variable not to call repeatedly.
Other Strategy?
Even so, you must hope to use objects from flexible classes like BaseModel in Pydantic.
from pydantic import BaseModel
class User(BaseModel):
name: str
tags: list = [] # Mutable Default Object
user1 = User(name="Kohei")
user2 = User(name="Kevin")
user1.tags.append("admin")
print(user1.tags) # ['admin']
print(user2.tags) # ['admin'] Expected Behavior: The changes made by user1 will be affected
default_factory
As like you see above, the same error happens even when you simply use BaseModel. The solution here is to use default_factory, then it will be solved.
from pydantic import BaseModel, Field
class User(BaseModel):
name: str
tags: list = Field(default_factory=list) # Create a list every initialization
user1 = User(name="Kohei")
user2 = User(name="Tanaka")
user1.tags.append("admin")
print(user1.tags) # ['admin']
print(user2.tags) # [] Expected Behavior