Tất cả mọi thứ trong Python là một đối tượng. Và điều mà mọi người mới đến Python nên nhanh chóng học được là tất cả các đối tượng trong Python có thể là thay đổi hoặc bất biến.mutable or immutable.
Hãy đi sâu hơn vào các chi tiết của nó, vì mọi thứ trong Python là một đối tượng, mọi biến đều giữ một thể hiện đối tượng. Khi một đối tượng được bắt đầu, nó được gán một ID đối tượng duy nhất. Loại của nó được xác định trong thời gian chạy và một khi được đặt không bao giờ có thể thay đổi, tuy nhiên trạng thái của nó có thể được thay đổi nếu nó có thể thay đổi. Nói một cách đơn giản, một đối tượng có thể thay đổi có thể được thay đổi sau khi nó được tạo ra và một đối tượng bất biến có thể.mutable object can be changed after it is created, and an immutable object can’t.
Các đối tượng của các loại tích hợp như [int, float, bool, str, tuple, unicode] là bất biến. Đối tượng của các loại tích hợp như [danh sách, tập hợp, dict] là có thể thay đổi. Các lớp tùy chỉnh thường có thể thay đổi. Để mô phỏng tính bất biến trong một lớp, người ta nên ghi đè cài đặt và xóa thuộc tính để tăng các ngoại lệ.
Bây giờ là câu hỏi, làm thế nào để chúng ta tìm ra nếu biến của chúng ta là một đối tượng có thể thay đổi hoặc bất biến. Đối với điều này, chúng ta nên hiểu các chức năng id id và gõ là gì.
Id và gõ
ID hàm tích hợp [] trả về danh tính của một đối tượng dưới dạng số nguyên. Số nguyên này thường tương ứng với vị trí đối tượng trong bộ nhớ, mặc dù điều này là cụ thể cho việc triển khai Python và nền tảng đang được sử dụng. Toán tử IS so sánh danh tính của hai đối tượng.id[] returns the identity of an object as an integer. This integer usually corresponds to the object’s location in memory, although this is specific to the Python implementation and the platform being used. The is operator compares the identity of two objects.
Loại chức năng tích hợp [] trả về loại đối tượng. Hãy xem một ví dụ đơn giản
''' Example 1 '''
>>> x = "Holberton"
>>> y = "Holberton"
>>> id[x]
140135852055856
>>> id[y]
140135852055856
>>> print[x is y] '''comparing the types'''
True''' Example 2 '''
>>> a = 50
>>> type[a]
>>> b = "Holberton"
>>> type[b]
Bây giờ chúng ta đã thấy cách so sánh hai biến chuỗi đơn giản để tìm ra các loại và ID.
Các đối tượng có thể thay đổi và bất biến
Vì vậy, như chúng ta đã thảo luận trước đó, một đối tượng có thể thay đổi có thể thay đổi trạng thái hoặc nội dung và các đối tượng bất biến không thể.
Các đối tượng có thể thay đổi::
Danh sách, Dict, Set, Byte Array
Đối tượng bất biến:
int, float, phức tạp, chuỗi, tuple, set frozen [Lưu ý: phiên bản bất biến của bộ], byte
Một ví dụ thực tế để tìm ra khả năng đột biến của các loại đối tượng
x = 10x = y
Chúng tôi đang tạo một đối tượng của loại int. Định danh X và Y trỏ đến cùng một đối tượng.
id[x] == id[y]id[y] == id[10]
Nếu chúng ta thực hiện một hoạt động đơn giản.
x = x + 1
Hiện nay
id[x] != id[y]id[x] != id[10]
Đối tượng trong đó x được gắn thẻ được thay đổi. Đối tượng 10 không bao giờ được sửa đổi. Các đối tượng bất biến không cho phép sửa đổi sau khi tạoImmutable objects doesn’t allow modification after creation
Trong trường hợp các đối tượng có thể thay đổimutable objects
m = list[[1, 2, 3]]n = m
Chúng tôi đang tạo một đối tượng của danh sách loại. Định danh M và M được gắn thẻ vào cùng một đối tượng Danh sách, đây là tập hợp 3 đối tượng INT bất biến.
id[m] == id[n]
Bây giờ việc xuất hiện một mục từ đối tượng danh sách không thay đổi đối tượng,
m.pop[]
ID đối tượng sẽ không được thay đổi
id[m] == id[n]
M và N sẽ chỉ vào cùng một đối tượng danh sách sau khi sửa đổi. Đối tượng danh sách bây giờ sẽ chứa [1, 2].
Vì vậy, những gì chúng ta đã thấy cho đến nay từ các ví dụ trên?
- Python xử lý các vật thể có thể thay đổi và bất biến khác nhau.
- Bất biến là nhanh hơn để truy cập hơn các đối tượng có thể thay đổi.
- Các đối tượng có thể thay đổi là tuyệt vời để sử dụng khi bạn cần thay đổi kích thước của đối tượng, danh sách ví dụ, chỉ đạo, v.v.
- Các đối tượng bất biến về cơ bản là tốn kém để thay đổi, bởi vì làm như vậy liên quan đến việc tạo một bản sao. Thay đổi đối tượng đột biến là rẻ.
Ngoại lệ trong tính bất biến ..
Không phải tất cả các đối tượng bất biến thực sự là bất biến. Bối rối? Hãy để tôi giải thích.
Như đã thảo luận trước đó, các container Python thích bộ dữ liệu là bất biến. Điều đó có nghĩa là giá trị của
x = 10x = y1 không thể thay đổi sau khi nó được tạo. Nhưng "giá trị" của một tuple là một chuỗi các tên có các ràng buộc không thể thay đổi với các đối tượng. Điều quan trọng cần lưu ý là các ràng buộc không thể thay đổi, không phải là các đối tượng mà chúng bị ràng buộc.
Chúng ta hãy xem xét một tuple t = [‘Holberton, [1, 2, 3]]t = [‘holberton’, [1, 2, 3]]
Tuple T ở trên chứa các phần tử của các loại dữ liệu khác nhau, loại đầu tiên là một chuỗi bất biến và loại thứ hai là một danh sách có thể thay đổi. Bản thân bộ tuple không thể thay đổi. tức là nó không có bất kỳ phương pháp nào để thay đổi nội dung của nó. Tương tự như vậy, chuỗi là bất biến vì các chuỗi don don có bất kỳ phương pháp đột biến nào. Nhưng đối tượng danh sách có các phương thức đột biến, vì vậy nó có thể được thay đổi. Đây là một điểm tinh tế, nhưng dù sao cũng quan trọng: giá trị của một đối tượng bất biến có thể thay đổi, nhưng nó có thể thay đổi đối tượng.t contains elements of different data types, the first one is an immutable string and the second one is a mutable list.The tuple itself isn’t mutable . i.e. it doesn’t have any methods for changing its contents. Likewise, the string is immutable because strings don’t have any mutating methods. But the list object does have mutating methods, so it can be changed. This is a subtle point, but nonetheless important: the “value” of an immutable object can’t change, but it’s constituent objects can.
Cách các đối tượng được truyền đến các chức năng
Điều quan trọng đối với chúng tôi là biết sự khác biệt giữa các loại có thể thay đổi và bất biến và cách chúng được đối xử khi được truyền vào các chức năng. Hiệu quả rất lớn bị ảnh hưởng khi sử dụng các đối tượng thích hợp.
Ví dụ: nếu một đối tượng có thể thay đổi được gọi bằng tham chiếu trong một hàm, nó có thể thay đổi chính biến ban đầu. Do đó, để tránh điều này, biến ban đầu cần được sao chép sang biến khác. Các đối tượng bất biến có thể được gọi bằng tham chiếu vì giá trị của nó không thể được thay đổi.
def updateList[list1]:
list1 += [10]n = [5, 6]
print[id[n]] # 140312184155336updateList[n]
print[n] # [5, 6, 10]
print[id[n]] # 140312184155336
Như chúng ta có thể thấy từ ví dụ trên, chúng ta đã gọi danh sách qua cuộc gọi bằng tham chiếu, vì vậy các thay đổi được thực hiện trong danh sách ban đầu.call by reference, so the changes are made to the original list itself.
Hãy xem một ví dụ khác:
x = 10x = y0
Trong ví dụ trên, cùng một đối tượng được truyền đến hàm, nhưng giá trị biến không thay đổi mặc dù đối tượng giống hệt nhau. Điều này được gọi là giá trị Passby. Vậy chính xác những gì đang xảy ra ở đây? Khi giá trị được gọi bởi hàm, chỉ có giá trị của biến được truyền, không phải chính đối tượng. Vì vậy, biến tham chiếu đối tượng không thay đổi, nhưng bản thân đối tượng đang được thay đổi nhưng chỉ trong phạm vi hàm. Do đó sự thay đổi không được phản ánh.pass by value. So what is exactly happening here? When the value is called by the function, only the value of the variable is passed, not the object itself. So the variable referencing the object is not changed, but the object itself is being changed but within the function scope only. Hence the change is not reflected.