Có thể quá tải trong Python không?

Nếu bạn đã sử dụng toán tử

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6 hoặc
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
7 trên đối tượng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8 trong Python, bạn hẳn đã nhận thấy hành vi khác biệt của nó khi so sánh với đối tượng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
9 hoặc
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
0

Show

>>>

>>> # Adds the two numbers
>>> 1 + 2
3

>>> # Concatenates the two strings
>>> 'Real' + 'Python'
'RealPython'


>>> # Gives the product
>>> 3 * 2
6

>>> # Repeats the string
>>> 'Python' * 3
'PythonPythonPython'

Bạn có thể thắc mắc làm thế nào mà cùng một toán tử hoặc hàm dựng sẵn lại hiển thị các hành vi khác nhau đối với các đối tượng thuộc các lớp khác nhau. Điều này được gọi là nạp chồng toán tử hoặc nạp chồng hàm tương ứng. Bài viết này sẽ giúp bạn hiểu cơ chế này, để bạn có thể thực hiện tương tự trong các lớp Python của riêng mình và làm cho các đối tượng của bạn giống Pythonic hơn

Bạn sẽ học những điều sau đây

  • API xử lý toán tử và tích hợp sẵn trong Python
  • “Bí mật” đằng sau
    >>> class Order:
    ..     def __init__(self, cart, customer):
    ..         self.cart = list(cart)
    ..         self.customer = customer
    ...
    >>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
    >>> len(order)  # Calling len when no __len__
    Traceback (most recent call last):
      File "", line 1, in 
    TypeError: object of type 'Order' has no len()
    
    1 và các phần mềm cài sẵn khác
  • Cách làm cho các lớp của bạn có khả năng sử dụng các toán tử
  • Cách làm cho các lớp của bạn tương thích với các hàm dựng sẵn của Python

Tiền thưởng miễn phí. Nhấp vào đây để có quyền truy cập vào Bảng cheat Python OOP miễn phí chỉ cho bạn các hướng dẫn, video và sách hay nhất để tìm hiểu thêm về Lập trình hướng đối tượng với Python

Ngoài ra, bạn cũng sẽ thấy một lớp ví dụ, các đối tượng của lớp này sẽ tương thích với nhiều toán tử và hàm này. Bắt đầu nào

Mô hình dữ liệu Python

Giả sử bạn có một lớp đại diện cho một đơn đặt hàng trực tuyến có một giỏ hàng (một

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
2) và một khách hàng (một
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8 hoặc phiên bản của một lớp khác đại diện cho một khách hàng)

Ghi chú. Nếu bạn cần xem lại OOP trong Python, hãy xem hướng dẫn này trên Real Python. Lập trình hướng đối tượng (OOP) trong Python 3

Trong trường hợp như vậy, việc muốn có được độ dài của danh sách giỏ hàng là điều hoàn toàn tự nhiên. Một người mới sử dụng Python có thể quyết định triển khai một phương thức có tên là

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
4 trong lớp của họ để thực hiện việc này. Nhưng bạn có thể định cấu hình
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 tích hợp theo cách nó trả về độ dài của danh sách giỏ hàng khi được cung cấp đối tượng của chúng ta

Trong một trường hợp khác, chúng tôi có thể muốn thêm thứ gì đó vào giỏ hàng. Một lần nữa, một người mới sử dụng Python sẽ nghĩ đến việc triển khai một phương thức có tên là

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
6 lấy một mặt hàng và thêm nó vào danh sách giỏ hàng. Nhưng bạn có thể định cấu hình toán tử
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6 theo cách nó thêm một mặt hàng mới vào giỏ hàng

Python thực hiện tất cả điều này bằng các phương thức đặc biệt. Các phương thức đặc biệt này có quy ước đặt tên, trong đó tên bắt đầu bằng hai dấu gạch dưới, theo sau là một mã định danh và kết thúc bằng một cặp dấu gạch dưới khác

Về cơ bản, mỗi hàm hoặc toán tử tích hợp có một phương thức đặc biệt tương ứng với nó. Ví dụ: có

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
8 tương ứng với
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 và
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 tương ứng với toán tử
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6

Theo mặc định, hầu hết các toán tử và tích hợp sẵn sẽ không hoạt động với các đối tượng trong lớp của bạn. Bạn phải thêm các phương thức đặc biệt tương ứng trong định nghĩa lớp của mình để làm cho đối tượng của bạn tương thích với các toán tử và tích hợp sẵn

Khi bạn thực hiện điều này, hành vi của hàm hoặc toán tử được liên kết với nó sẽ thay đổi theo hành vi được xác định trong phương thức

Đây chính là điều mà Mô hình dữ liệu (Phần 3 của tài liệu Python) giúp bạn hoàn thành. Nó liệt kê tất cả các phương thức đặc biệt có sẵn và cung cấp cho bạn phương tiện nạp chồng các hàm và toán tử dựng sẵn để bạn có thể sử dụng chúng trên các đối tượng của riêng mình

Hãy xem điều này có nghĩa là gì

Sự thật thú vị. Do quy ước đặt tên được sử dụng cho các phương thức này, chúng còn được gọi là phương thức dunder, viết tắt của phương thức gạch dưới kép. Đôi khi chúng còn được gọi là phương pháp đặc biệt hoặc phương pháp ma thuật. Mặc dù vậy, chúng tôi thích các phương pháp dunder hơn

Loại bỏ các quảng cáo

Nội bộ của các hoạt động như >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... >>> order = Order(['banana', 'apple', 'mango'], 'Real Python') >>> len(order) # Calling len when no __len__ Traceback (most recent call last): File "", line 1, in TypeError: object of type 'Order' has no len() 1 và >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... .. def __len__(self): .. return float(len(self.cart)) # Return type changed to float ... >>> order = Order(['banana', 'apple', 'mango'], 'Real Python') >>> len(order) Traceback (most recent call last): File "", line 1, in TypeError: 'float' object cannot be interpreted as an integer 3

Mỗi lớp trong Python định nghĩa hành vi riêng của nó cho các hàm và phương thức tích hợp. Khi bạn chuyển một thể hiện của một số lớp cho một hàm dựng sẵn hoặc sử dụng một toán tử trên thể hiện đó, nó thực sự tương đương với việc gọi một phương thức đặc biệt với các đối số liên quan

Nếu có một hàm dựng sẵn,

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
4 và phương thức đặc biệt tương ứng cho hàm đó là
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
5, thì Python diễn giải lời gọi hàm là
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
6, trong đó
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
7 là đối tượng. Trong trường hợp toán tử, nếu bạn có một toán tử
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
8 và phương thức đặc biệt tương ứng cho nó là
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
9, thì Python diễn giải một cái gì đó như
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
0 thành
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
1

Vì vậy, khi bạn đang gọi

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 trên một đối tượng, Python sẽ xử lý cuộc gọi là
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
3. Khi bạn sử dụng toán tử
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
3 trên một đối tượng có thể lặp lại để lấy giá trị tại một chỉ mục, Python sẽ xử lý nó dưới dạng
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
5, trong đó
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
6 là đối tượng có thể lặp lại và
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
7 là chỉ mục bạn muốn lấy

Do đó, khi bạn định nghĩa các phương thức đặc biệt này trong lớp của riêng mình, bạn sẽ ghi đè hành vi của hàm hoặc toán tử được liên kết với chúng bởi vì, đằng sau hậu trường, Python đang gọi phương thức của bạn. Hãy hiểu rõ hơn về điều này

>>>_______ 33 _______

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'

Như bạn có thể thấy, khi bạn sử dụng hàm hoặc phương thức đặc biệt tương ứng của nó, bạn sẽ nhận được kết quả tương tự. Trên thực tế, khi bạn lấy danh sách các thuộc tính và phương thức của một đối tượng

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8 bằng cách sử dụng
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
9, bạn sẽ thấy các phương thức đặc biệt này trong danh sách bên cạnh các phương thức thông thường có sẵn trên các đối tượng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8

>>>

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

Nếu hành vi của một hàm hoặc toán tử tích hợp sẵn không được định nghĩa trong lớp bằng phương thức đặc biệt, thì bạn sẽ nhận được một

>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
1

Vì vậy, làm thế nào bạn có thể sử dụng các phương pháp đặc biệt trong các lớp học của mình?

Quá tải chức năng tích hợp

Nhiều phương pháp đặc biệt được xác định trong Mô hình Dữ liệu có thể được sử dụng để thay đổi hành vi của các hàm, chẳng hạn như

>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
2,
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
3,
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
4,
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
5, v.v. Để làm điều này, bạn chỉ cần định nghĩa phương thức đặc biệt tương ứng trong lớp của mình. Hãy xem xét một vài ví dụ

Đưa ra chiều dài cho các đối tượng của bạn bằng cách sử dụng >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... >>> order = Order(['banana', 'apple', 'mango'], 'Real Python') >>> len(order) # Calling len when no __len__ Traceback (most recent call last): File "", line 1, in TypeError: object of type 'Order' has no len() 1

Để thay đổi hành vi của

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1, bạn cần xác định phương thức đặc biệt của
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
8 trong lớp của mình. Bất cứ khi nào bạn chuyển một đối tượng trong lớp của mình tới
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1, định nghĩa tùy chỉnh của bạn về
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
8 sẽ được sử dụng để thu được kết quả. Hãy triển khai
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 cho lớp thứ tự mà chúng ta đã nói ở phần đầu

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3

Như bạn có thể thấy, bây giờ bạn có thể sử dụng

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 để lấy trực tiếp chiều dài của xe đẩy. Hơn nữa, sẽ có ý nghĩa trực quan hơn khi nói “độ dài của đơn đặt hàng” thay vì gọi một cái gì đó như
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __repr__(self):
..         return f'Vector({self.x_comp}, {self.y_comp})'
...

>>> vector = Vector(3, 4)
>>> repr(vector)
'Vector(3, 4)'

>>> b = eval(repr(vector))
>>> type(b), b.x_comp, b.y_comp
(__main__.Vector, 3, 4)

>>> vector  # Looking at object; __repr__ used
'Vector(3, 4)'
3. Cuộc gọi của bạn vừa Pythonic vừa trực quan hơn. Khi bạn không xác định phương thức
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
8 nhưng vẫn gọi
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 trên đối tượng của mình, bạn sẽ nhận được một
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
1

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()

Nhưng, khi quá tải

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1, bạn nên nhớ rằng Python yêu cầu hàm trả về một số nguyên. Nếu phương thức của bạn trả về bất kỳ giá trị nào khác ngoài số nguyên, thì bạn sẽ nhận được _____38_______1. Điều này, rất có thể, là để giữ cho nó phù hợp với thực tế là
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1 thường được sử dụng để lấy độ dài của một dãy, mà chỉ có thể là một số nguyên

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer

Làm cho các đối tượng của bạn hoạt động với >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... .. def __bool__(self): .. return len(self.cart) > 0 ... >>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python') >>> order2 = Order([], 'Python') >>> bool(order1) True >>> bool(order2) False >>> for order in [order1, order2]: .. if order: .. print(f"{order.customer}'s order is processing...") .. else: .. print(f"Empty order for customer {order.customer}") Real Python's order is processing... Empty order for customer Python 0

Bạn có thể ra lệnh cho hành vi của các đối tượng trong lớp của mình bằng cách định nghĩa phương thức đặc biệt

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
2 trong lớp. Không có giới hạn nào đối với giá trị trả về của
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
0 và bạn nhận được một
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
1 khi phương thức đặc biệt không có trong định nghĩa lớp của bạn

Trong một lớp biểu diễn một vectơ trong không gian hai chiều, có thể sử dụng

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
0 để lấy độ dài của vectơ. Hãy xem nó hoạt động

>>>

>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0

Nói “giá trị tuyệt đối của vectơ” sẽ có ý nghĩa trực quan hơn là gọi một cái gì đó như

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
6

Loại bỏ các quảng cáo

In đối tượng của bạn đẹp mắt bằng cách sử dụng >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... .. def __bool__(self): .. return len(self.cart) > 0 ... >>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python') >>> order2 = Order([], 'Python') >>> bool(order1) True >>> bool(order2) False >>> for order in [order1, order2]: .. if order: .. print(f"{order.customer}'s order is processing...") .. else: .. print(f"Empty order for customer {order.customer}") Real Python's order is processing... Empty order for customer Python 7

Tích hợp sẵn

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
7 được sử dụng để truyền một thể hiện của một lớp tới một đối tượng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8, hoặc thích hợp hơn, để có được một biểu diễn chuỗi thân thiện với người dùng của đối tượng mà người dùng bình thường có thể đọc được chứ không phải lập trình viên. Bạn có thể xác định định dạng chuỗi mà đối tượng của bạn sẽ được hiển thị khi được chuyển đến
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
7 bằng cách xác định phương thức
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 trong lớp của bạn. Hơn nữa,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 là phương thức được Python sử dụng khi bạn gọi _______33_______03 trên đối tượng của mình

Hãy triển khai điều này trong lớp

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
04 để định dạng các đối tượng
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
04 thành
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
06. Thành phần y âm sẽ được xử lý bằng cách sử dụng

>>>_______ 38 _______

>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j

Điều cần thiết là

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 trả về một đối tượng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8 và chúng tôi nhận được một
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
1 nếu kiểu trả về không phải là chuỗi

Đại diện cho các đối tượng của bạn bằng cách sử dụng >>> a = 'Real Python' >>> b = ['Real', 'Python'] >>> len(a) 11 >>> a.__len__() 11 >>> b[0] 'Real' >>> b.__getitem__(0) 'Real' 10

Tích hợp sẵn

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
10 được sử dụng để lấy biểu diễn chuỗi có thể phân tích cú pháp của một đối tượng. Nếu một đối tượng có thể phân tích cú pháp, điều đó có nghĩa là Python sẽ có thể tạo lại đối tượng từ biểu diễn khi
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
12 được sử dụng cùng với các hàm như
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
13. Để xác định hành vi của
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
10, bạn có thể sử dụng phương thức đặc biệt của
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15

Đây cũng là phương thức Python sử dụng để hiển thị đối tượng trong phiên REPL. Nếu phương thức

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 không được xác định, bạn sẽ nhận được một cái gì đó giống như
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
17 khi cố gắng xem xét đối tượng trong phiên REPL. Hãy xem nó hoạt động trong lớp
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
04

>>>

>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __repr__(self):
..         return f'Vector({self.x_comp}, {self.y_comp})'
...

>>> vector = Vector(3, 4)
>>> repr(vector)
'Vector(3, 4)'

>>> b = eval(repr(vector))
>>> type(b), b.x_comp, b.y_comp
(__main__.Vector, 3, 4)

>>> vector  # Looking at object; __repr__ used
'Vector(3, 4)'

Ghi chú. Trong trường hợp phương thức

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 không được định nghĩa, Python sử dụng phương thức
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 để in đối tượng, cũng như để biểu diễn đối tượng khi
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
7 được gọi trên nó. Nếu thiếu cả hai phương thức, nó sẽ mặc định là
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
22. Nhưng
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 là phương pháp duy nhất được sử dụng để hiển thị đối tượng trong phiên tương tác. Sự vắng mặt của nó trong lớp mang lại
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
22

Ngoài ra, trong khi sự khác biệt này giữa

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 và
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 là hành vi được khuyến nghị, nhiều thư viện phổ biến bỏ qua sự khác biệt này và sử dụng hai phương pháp thay thế cho nhau

Đây là một bài viết được đề xuất về

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 và
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 bởi chính Dan Bader của chúng tôi. Chuyển đổi chuỗi Python 101. Tại sao mọi lớp học đều cần một "đại diện"

Làm cho đối tượng của bạn thành thật hoặc giả bằng cách sử dụng ________ 33 _______ 29

Có thể sử dụng

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
29 tích hợp để lấy giá trị thực của một đối tượng. Để xác định hành vi của nó, bạn có thể sử dụng
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
31 (
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
32 trong Python 2. x) phương pháp đặc biệt

Hành vi được xác định ở đây sẽ xác định giá trị thực của một thể hiện trong tất cả các ngữ cảnh yêu cầu lấy giá trị thực, chẳng hạn như trong các câu lệnh

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
33

Ví dụ, đối với lớp

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
34 đã được định nghĩa ở trên, một thể hiện có thể được coi là trung thực nếu độ dài của danh sách giỏ hàng khác không. Điều này có thể được sử dụng để kiểm tra xem một đơn đặt hàng có nên được xử lý hay không

>>>_______ 60 _______

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python

Ghi chú. Khi phương pháp đặc biệt

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
31 không được triển khai trong một lớp, giá trị trả về bởi
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __str__(self):
..         # By default, sign of +ve number is not displayed
..         # Using `+`, sign is always displayed
..         return f'{self.x_comp}i{self.y_comp:+}j'
...
>>> vector = Vector(3, 4)
>>> str(vector)
'3i+4j'
>>> print(vector)
3i+4j
8 được sử dụng làm giá trị thực, trong đó giá trị khác 0 biểu thị
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
37 và giá trị 0 biểu thị
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
38. Trong trường hợp cả hai phương thức không được triển khai, tất cả các thể hiện của lớp được coi là
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
37

Có nhiều phương thức đặc biệt hơn làm quá tải các hàm tích hợp. Bạn có thể tìm thấy chúng trong. Đã thảo luận về một số trong số họ, hãy chuyển sang các toán tử

Quá tải các toán tử tích hợp

Thay đổi hành vi của toán tử cũng đơn giản như thay đổi hành vi của hàm. Bạn định nghĩa các phương thức đặc biệt tương ứng của chúng trong lớp của mình và các toán tử hoạt động theo hành vi được xác định trong các phương thức này

Chúng khác với các phương thức đặc biệt ở trên theo nghĩa là chúng cần chấp nhận một đối số khác trong định nghĩa ngoài

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
40, thường được gọi bằng tên
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
41. Hãy xem xét một vài ví dụ

Loại bỏ các quảng cáo

Làm cho các đối tượng của bạn có khả năng được thêm vào bằng cách sử dụng >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... .. def __len__(self): .. return len(self.cart) ... >>> order = Order(['banana', 'apple', 'mango'], 'Real Python') >>> len(order) 3 6

Phương thức đặc biệt tương ứng với toán tử

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6 là phương thức
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0. Việc thêm định nghĩa tùy chỉnh của
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 sẽ thay đổi hành vi của người vận hành. Khuyến nghị rằng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 trả về một thể hiện mới của lớp thay vì sửa đổi chính thể hiện đang gọi. Bạn sẽ thấy hành vi này khá phổ biến trong Python

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
0

Bạn có thể thấy ở trên rằng việc sử dụng toán tử

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6 trên một đối tượng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8 thực sự trả về một phiên bản
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
8 mới, giữ nguyên giá trị của phiên bản đang gọi (
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
50). Để thay đổi nó, chúng ta cần chỉ định rõ ràng phiên bản mới cho
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
50

Hãy triển khai khả năng thêm các mặt hàng mới vào giỏ hàng của chúng ta trong lớp

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
34 bằng cách sử dụng toán tử. Chúng tôi sẽ làm theo phương pháp được đề xuất và yêu cầu toán tử trả lại một phiên bản
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
34 mới có các thay đổi theo yêu cầu của chúng tôi thay vì thực hiện các thay đổi trực tiếp với phiên bản của chúng tôi

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
1

Tương tự, bạn có

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
54,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
55 và các phương pháp đặc biệt khác xác định hành vi của
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
56,
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
7, v.v. Các phương thức này cũng sẽ trả về một thể hiện mới của lớp

phím tắt. Người điều hành >>> a = 'Real Python' >>> b = ['Real', 'Python'] >>> len(a) 11 >>> a.__len__() 11 >>> b[0] 'Real' >>> b.__getitem__(0) 'Real' 58

Toán tử

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
58 là viết tắt của biểu thức
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
60. Phương thức đặc biệt tương ứng với nó là
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61. Phương thức
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61 sẽ thực hiện các thay đổi trực tiếp đối với đối số
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
40 và trả về kết quả, có thể hoặc không thể là
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
40. Hành vi này hoàn toàn khác với
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 vì cái sau tạo một đối tượng mới và trả về đối tượng đó, như bạn đã thấy ở trên

Đại khái, bất kỳ cách sử dụng

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
58 nào đối với hai đối tượng đều tương đương với điều này

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
2

Ở đây,

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
67 là giá trị được trả về bởi
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61. Phép gán thứ hai được Python tự động xử lý, có nghĩa là bạn không cần gán rõ ràng
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
69 cho kết quả như trong trường hợp của
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
60

Hãy biến điều này thành có thể đối với lớp

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
34 để các mặt hàng mới có thể được thêm vào giỏ hàng bằng cách sử dụng
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
58

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
3

Như có thể thấy, bất kỳ thay đổi nào được thực hiện trực tiếp tới

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
40 và sau đó được trả lại. Điều gì xảy ra khi bạn trả về một số giá trị ngẫu nhiên, chẳng hạn như một chuỗi hoặc một số nguyên?

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
4

Mặc dù mặt hàng có liên quan đã được thêm vào giỏ hàng, nhưng giá trị của

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
74 đã thay đổi thành giá trị được trả lại bởi
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61. Python đã ngầm xử lý bài tập cho bạn. Điều này có thể dẫn đến hành vi đáng ngạc nhiên nếu bạn quên trả lại thứ gì đó trong quá trình triển khai của mình

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
5

Vì tất cả các hàm (hoặc phương thức) Python hoàn toàn trả về

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
76, nên
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
74 được gán lại cho
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
76 và phiên REPL không hiển thị bất kỳ đầu ra nào khi kiểm tra
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
74. Nhìn vào loại
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
74, bạn thấy rằng bây giờ nó là
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
81. Do đó, hãy luôn đảm bảo rằng bạn đang trả lại thứ gì đó khi triển khai
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61 và đó là kết quả của hoạt động chứ không phải bất kỳ thứ gì khác

Tương tự với

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61, bạn có
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
84,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
85,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
86 và các phương pháp đặc biệt khác để xác định hành vi của
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
87,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
88,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
89 và những phương thức tương tự

Ghi chú. Khi

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61 hoặc các bạn của nó bị thiếu trong định nghĩa lớp của bạn nhưng bạn vẫn sử dụng các toán tử của chúng trên các đối tượng của mình, Python sử dụng
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 và các bạn của nó để lấy kết quả của phép toán và gán kết quả đó cho thể hiện gọi. Nói chung, sẽ an toàn nếu không triển khai
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
61 và những người bạn của nó trong lớp học của bạn miễn là
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 và những người bạn của nó hoạt động bình thường (trả lại thứ gì đó là kết quả của hoạt động)

Python có một lời giải thích tốt về các phương pháp này. Ngoài ra, hãy xem ví dụ cho thấy những cảnh báo liên quan đến

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
58 và những thứ khác khi làm việc với các loại không thay đổi

Loại bỏ các quảng cáo

Lập chỉ mục và cắt các đối tượng của bạn bằng cách sử dụng >>> class Order: .. def __init__(self, cart, customer): .. self.cart = list(cart) .. self.customer = customer ... .. def __len__(self): .. return float(len(self.cart)) # Return type changed to float ... >>> order = Order(['banana', 'apple', 'mango'], 'Real Python') >>> len(order) Traceback (most recent call last): File "", line 1, in TypeError: 'float' object cannot be interpreted as an integer 3

Toán tử

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
3 được gọi là toán tử lập chỉ mục và được sử dụng trong nhiều ngữ cảnh khác nhau trong Python, chẳng hạn như lấy giá trị tại một chỉ mục theo trình tự, lấy giá trị được liên kết với một khóa trong từ điển hoặc lấy một phần của chuỗi thông qua việc cắt. Bạn có thể thay đổi hành vi của nó bằng cách sử dụng phương pháp đặc biệt
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
97

Hãy định cấu hình lớp

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
34 của chúng ta để chúng ta có thể trực tiếp sử dụng đối tượng và lấy một mặt hàng từ giỏ hàng

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
6

Bạn sẽ nhận thấy rằng ở trên, tên của đối số của

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
97 không phải là
>>> class Vector:
..     def __init__(self, x_comp, y_comp):
..         self.x_comp = x_comp
..         self.y_comp = y_comp
...
..     def __abs__(self):
..         return (self.x_comp ** 2 + self.y_comp ** 2) ** 0.5
...
>>> vector = Vector(3, 4)
>>> abs(vector)
5.0
7 mà là
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
01. Điều này là do đối số có thể có ba hình thức chủ yếu. một giá trị số nguyên, trong trường hợp đó là chỉ mục hoặc khóa từ điển, giá trị chuỗi, trong trường hợp đó là khóa từ điển và , trong trường hợp đó, nó sẽ cắt chuỗi được sử dụng bởi lớp. Mặc dù có những khả năng khác, nhưng đây là những khả năng thường gặp nhất

Vì cấu trúc dữ liệu bên trong của chúng ta là một danh sách, nên chúng ta có thể sử dụng toán tử

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
3 để cắt danh sách, như trong trường hợp này, đối số
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
01 sẽ là một đối tượng lát. Đây là một trong những lợi thế lớn nhất của việc có một định nghĩa
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
97 trong lớp học của bạn. Miễn là bạn đang sử dụng cấu trúc dữ liệu hỗ trợ cắt (danh sách, bộ dữ liệu, chuỗi, v.v.), bạn có thể định cấu hình các đối tượng của mình để trực tiếp cắt cấu trúc

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
7

Ghi chú. Có một phương pháp đặc biệt tương tự

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
05 được sử dụng để xác định hành vi của
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
06. Phương pháp này nhận hai đối số ngoài
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
40, thường được gọi là
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
01 và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
09, và có thể được sử dụng để thay đổi giá trị tại
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
01 thành
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
09

toán tử đảo ngược. Làm cho lớp học của bạn chính xác về mặt toán học

Trong khi định nghĩa

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
54,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
55 và các phương thức đặc biệt tương tự cho phép bạn sử dụng các toán tử khi đối tượng lớp của bạn là toán hạng bên trái, toán tử sẽ không hoạt động nếu đối tượng lớp là toán hạng bên phải

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
8

Nếu lớp của bạn đại diện cho một thực thể toán học như vectơ, tọa độ hoặc số phức, thì việc áp dụng các toán tử sẽ hoạt động trong cả hai trường hợp vì đây là một phép toán hợp lệ

Hơn nữa, nếu các toán tử chỉ hoạt động khi thể hiện là toán hạng bên trái, chúng ta đang vi phạm nguyên tắc cơ bản của tính giao hoán trong nhiều trường hợp. Do đó, để giúp bạn làm cho các lớp của mình chính xác về mặt toán học, Python cung cấp cho bạn các phương thức đảo ngược đặc biệt như

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
15,
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
16,
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
17, v.v.

Các cuộc gọi xử lý này chẳng hạn như

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
18,
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
19 và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
20, trong đó
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
21 không phải là một thể hiện của lớp liên quan. Cũng giống như
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 và các phương thức khác, các phương thức đảo ngược đặc biệt này sẽ trả về một thể hiện mới của lớp với các thay đổi của thao tác thay vì sửa đổi chính thể hiện đang gọi

Hãy định cấu hình

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
15 trong lớp
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
34 theo cách nó sẽ nối thêm một thứ gì đó ở phía trước giỏ hàng. Điều này có thể được sử dụng trong trường hợp giỏ hàng được sắp xếp theo mức độ ưu tiên của các đơn đặt hàng

>>>

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
9

Một ví dụ hoàn chỉnh

Để đưa tất cả những điểm này về nhà, tốt hơn là xem xét một lớp ví dụ triển khai các toán tử này cùng nhau

Hãy phát minh lại bánh xe và triển khai lớp của riêng chúng ta để biểu diễn các số phức,

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
25. Các đối tượng của lớp chúng ta sẽ hỗ trợ nhiều hàm và toán tử dựng sẵn, làm cho chúng hoạt động rất giống với lớp số phức dựng sẵn

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
0

Hàm tạo chỉ xử lý một loại cuộc gọi,

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
26. Nó nhận các đối số vị trí, biểu diễn phần thực và phần ảo của số phức

Hãy định nghĩa hai phương thức bên trong lớp,

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
27 và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
28, sẽ cung cấp cho chúng ta liên hợp phức và đối số của một số phức tương ứng

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
1

Ghi chú.

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
29 không phải là một phương thức đặc biệt mà là một thuộc tính lớp được mặc định. Nó có một tham chiếu đến lớp. Bằng cách sử dụng nó ở đây, chúng tôi có được điều đó và sau đó gọi hàm tạo theo cách thông thường. Nói cách khác, điều này tương đương với
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
30. Điều này được thực hiện ở đây để tránh cấu trúc lại mã nếu tên của lớp thay đổi vào một ngày nào đó

Tiếp theo, chúng tôi định cấu hình

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
0 để trả về mô đun của một số phức

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
2

Chúng tôi sẽ tuân theo sự phân biệt được khuyến nghị giữa

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 và
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 và sử dụng cách đầu tiên để biểu diễn chuỗi có thể phân tích cú pháp và cách thứ hai để biểu diễn "đẹp"

Phương thức

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
15 sẽ chỉ trả về
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
26 trong một chuỗi để chúng ta có thể gọi
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
13 để tạo lại đối tượng, trong khi phương thức
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
01 sẽ trả về số phức trong ngoặc đơn, như
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
38

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
3

Về mặt toán học, có thể cộng hai số phức bất kỳ hoặc cộng một số thực thành một số phức. Hãy cấu hình toán tử

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6 sao cho nó hoạt động cho cả hai trường hợp

Phương thức sẽ kiểm tra loại toán tử bên tay phải. Trong trường hợp là một số

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
9 hoặc một số
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
0, nó sẽ chỉ tăng phần thực (vì bất kỳ số thực nào,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
50, đều tương đương với
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
43), trong khi đối với một số phức khác, nó sẽ thay đổi cả hai phần

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
4

Tương tự, chúng tôi xác định hành vi cho

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
56 và
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
7

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
5

Vì cả phép cộng và phép nhân đều có tính chất giao hoán, nên chúng ta có thể định nghĩa các toán tử đảo ngược của chúng bằng cách gọi

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return float(len(self.cart))  # Return type changed to float
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer
0 và
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
55 lần lượt trong
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
15 và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
17. Mặt khác, hành vi của
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
16 cần được xác định vì phép trừ không có tính chất giao hoán

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
6

Ghi chú. Bạn có thể nhận thấy rằng chúng tôi đã không thêm một cấu trúc để xử lý một phiên bản

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
25 ở đây. Điều này là do, trong trường hợp như vậy, cả hai toán hạng đều là thể hiện của lớp chúng ta và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
16 sẽ không chịu trách nhiệm xử lý thao tác. Thay vào đó,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
54 sẽ được gọi. Đây là một chi tiết tinh tế nhưng quan trọng

Bây giờ, chúng tôi xử lý hai toán tử,

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
54 và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
55. Các phương pháp đặc biệt được sử dụng cho chúng lần lượt là
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
56 và
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
57. Hai số phức được gọi là bằng nhau nếu phần thực và phần ảo tương ứng của chúng bằng nhau. Chúng được cho là không bằng nhau khi một trong hai cái này không bằng nhau

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
7

Ghi chú. Hướng dẫn dấu phẩy động là một bài viết nói về việc so sánh số float và độ chính xác của dấu phẩy động. Nó làm nổi bật những cảnh báo liên quan đến việc so sánh số float một cách trực tiếp, đó là điều chúng tôi đang làm ở đây

Cũng có thể nâng một số phức lên bất kỳ lũy thừa nào bằng công thức đơn giản. Chúng tôi định cấu hình hành vi cho cả toán tử

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
58 và toán tử
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
59 tích hợp bằng cách sử dụng phương pháp đặc biệt
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
60

>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
8

Ghi chú. Hãy xem kỹ định nghĩa của phương pháp. Chúng tôi đang gọi

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
0 để lấy mô đun của số phức. Vì vậy, một khi bạn đã xác định phương thức đặc biệt cho một hàm hoặc toán tử cụ thể trong lớp của mình, nó có thể được sử dụng trong các phương thức khác của cùng một lớp

Hãy tạo hai thể hiện của lớp này, một thể hiện có phần ảo dương và một thể hiện có phần ảo âm

>>> ______37_______9

biểu diễn chuỗi

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
0

Tạo lại đối tượng bằng cách sử dụng

>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
13 với
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
10

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
1

Phép cộng, phép trừ và phép nhân

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
2

Kiểm tra đẳng thức và bất đẳng thức

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
3

Cuối cùng, nâng một số phức lên một số lũy thừa

>>>

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
4

Như bạn có thể thấy, các đối tượng của lớp tùy chỉnh của chúng ta hoạt động và trông giống như các đối tượng của lớp dựng sẵn và rất Pythonic. Mã ví dụ đầy đủ cho lớp này được nhúng bên dưới

Giải pháp. "Ví dụ hoàn chỉnh"Hiển thị/Ẩn

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
5

Loại bỏ các quảng cáo

Tóm tắt và Tài nguyên

Trong hướng dẫn này, bạn đã tìm hiểu về Mô hình dữ liệu Python và cách Mô hình dữ liệu có thể được sử dụng để xây dựng các lớp Pythonic. Bạn đã học về cách thay đổi hành vi của các chức năng tích hợp sẵn, chẳng hạn như

>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)  # Calling len when no __len__
Traceback (most recent call last):
  File "", line 1, in 
TypeError: object of type 'Order' has no len()
1,
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
0,
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __bool__(self):
..         return len(self.cart) > 0
...
>>> order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> order2 = Order([], 'Python')

>>> bool(order1)
True
>>> bool(order2)
False

>>> for order in [order1, order2]:
..     if order:
..         print(f"{order.customer}'s order is processing...")
..     else:
..         print(f"Empty order for customer {order.customer}")
Real Python's order is processing...
Empty order for customer Python
7,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
29, v.v. Bạn cũng đã học về cách thay đổi hành vi của các toán tử tích hợp sẵn như
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
6,
>>> a = 'Real Python'
>>> b = ['Real', 'Python']
>>> len(a)
11
>>> a.__len__()
11
>>> b[0]
'Real'
>>> b.__getitem__(0)
'Real'
56,
>>> class Order:
..     def __init__(self, cart, customer):
..         self.cart = list(cart)
..         self.customer = customer
...
..     def __len__(self):
..         return len(self.cart)
...
>>> order = Order(['banana', 'apple', 'mango'], 'Real Python')
>>> len(order)
3
7,
>>> dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 ...,
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 ...,
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']
59, v.v.

Tiền thưởng miễn phí. Nhấp vào đây để có quyền truy cập vào Bảng cheat Python OOP miễn phí chỉ cho bạn các hướng dẫn, video và sách hay nhất để tìm hiểu thêm về Lập trình hướng đối tượng với Python

Sau khi đọc phần này, bạn có thể tự tin tạo các lớp sử dụng các tính năng thành ngữ tốt nhất của Python và biến các đối tượng của bạn thành Pythonic

Để biết thêm thông tin về Mô hình Dữ liệu cũng như quá tải hàm và toán tử, hãy xem các tài nguyên này

  • của phần Mô hình dữ liệu trong tài liệu Python
  • Thông thạo Python của Luciano Ramalho
  • Thủ thuật Python. Quyển sách

Đánh dấu là đã hoàn thành

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Có thể quá tải trong Python không?

Gửi cho tôi thủ thuật Python »

Về Malay Agarwal

Có thể quá tải trong Python không?
Có thể quá tải trong Python không?

Một người đam mê công nghệ với đầu óc triết học và một bàn tay có thể cầm bút

» Tìm hiểu thêm về tiếng Mã Lai


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Có thể quá tải trong Python không?

David

Có thể quá tải trong Python không?

Đan

Có thể quá tải trong Python không?

Geir Arne

Có thể quá tải trong Python không?

Joanna

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Chuyên gia Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Chúng ta có thể quá tải trong Python không?

Python không hỗ trợ nạp chồng hàm . Khi chúng ta định nghĩa nhiều hàm có cùng tên, hàm sau luôn ghi đè lên hàm trước và do đó, trong không gian tên, sẽ luôn có một mục duy nhất đối với mỗi tên hàm.

Có thể quá tải và ghi đè trong Python không?

Python không hỗ trợ nạp chồng phương thức . Ghi đè phương thức là định nghĩa lại một phương thức của lớp cha trong lớp dẫn xuất. Ghi đè yêu cầu kế thừa để thực hiện.

Tại sao không thể nạp chồng phương thức trong Python?

Không thể quyết định thực thi phương thức nào dựa trên kiểu trả về, do đó, không thể nạp chồng chỉ bằng cách thay đổi kiểu trả về của phương thức

Chúng ta có thể quá tải toán tử () không?

Nạp chồng toán tử gọi hàm () trong C++ . Khi bạn quá tải ( ), bạn không tạo ra một cách mới để gọi một hàm. Thay vào đó, bạn đang tạo một hàm toán tử có thể được truyền một số tham số tùy ý. The function call operator () can be overloaded for objects of class type. When you overload ( ), you are not creating a new way to call a function. Rather, you are creating an operator function that can be passed an arbitrary number of parameters.