Nó xảy ra bởi vì quá trình biên dịch trong Python được thực hiện bằng cách thực thi mã mô tả.
Nếu một người nói
def f(x = {}):
....
sẽ khá rõ ràng rằng bạn muốn có một mảng mới mỗi lần.
Nhưng nếu tôi nói:
list_of_all = {}
def create(stuff, x = list_of_all):
...
Ở đây tôi đoán tôi muốn tạo nội dung vào nhiều danh sách khác nhau và có một danh sách toàn cầu duy nhất khi tôi không chỉ định danh sách.
Nhưng làm thế nào trình biên dịch sẽ đoán điều này? Vậy tại sao phải thử? Chúng ta có thể dựa vào việc cái này có được đặt tên hay không, và đôi khi nó có thể giúp ích, nhưng thực sự nó chỉ là phỏng đoán. Đồng thời, có một lý do chính đáng để không thử - tính nhất quán.
Như nó là, Python chỉ thực thi mã. Biến list_of_all đã được gán một đối tượng, do đó, đối tượng đó được chuyển bằng tham chiếu vào mã mặc định x theo cách mà một lệnh gọi đến bất kỳ hàm nào sẽ nhận được tham chiếu đến một đối tượng cục bộ có tên ở đây.
Nếu chúng ta muốn phân biệt tên chưa được đặt tên với trường hợp được đặt tên, thì điều đó sẽ liên quan đến mã khi biên dịch thực thi gán theo một cách khác đáng kể so với nó được thực thi trong thời gian chạy. Vì vậy, chúng tôi không làm cho trường hợp đặc biệt.