Hướng dẫn dunder trong python - dunder in python

  • Trang chủ
  • Lập trình Python
  • Phương thức Magic hoặc Dunder trong Python

Trong hướng dẫn này chúng ta sẽ đi tìm hiểu về phương thức Magic và Nạp chồng toán tử (operator overloading) trong lập trình Python

Nội dung chính

  • Magic method trong lập trình Python
  • Ghi đè phương thức __new__()
  • Ghi đè phương thức __str__() và __repr__()
  • Nạp chồng các phép toán số học
  • Bài viết này đã giúp ích cho bạn?

Như bạn đã biết, Python định nghĩa sẵn một số phép toán trên các kiểu dữ liệu của mình. Ví dụ, phép cộng (+) đã được định nghĩa sẵn cho các kiểu số, kiểu xâu ký tự, kiểu danh sách.

Giả sử bạn xây dựng kiểu dữ liệu riêng (class) Matrix (ma trận). Do ma trận cũng có các phép toán như phép cộng, phép nhân, bạn cũng muốn trực tiếp áp dụng các phép toán này cho object của lớp Matrix.

Khi này bạn sẽ cần sử dụng đến kỹ thuật nạp chồng toán tử.

Nạp chồng toán tử (operator overloading) là kỹ thuật định nghĩa các phép toán sẵn có trên kiểu dữ liệu tự tạo. (operator overloading) là kỹ thuật định nghĩa các phép toán sẵn có trên kiểu dữ liệu tự tạo.

Trong Python nạp chồng toán tử hoạt động tương đối khác với ngôn ngữ như C++/Java/C#. Các toán tử trong Python hoạt động dựa trên một số magic method.

Magic method trong lập trình Python

Ghi đè phương thức __new__()

Ghi đè phương thức __str__() và __repr__()

Nạp chồng các phép toán số học

Bài viết này đã giúp ích cho bạn?

Như bạn đã biết, Python định nghĩa sẵn một số phép toán trên các kiểu dữ liệu của mình. Ví dụ, phép cộng (+) đã được định nghĩa sẵn cho các kiểu số, kiểu xâu ký tự, kiểu danh sách.

Giả sử bạn xây dựng kiểu dữ liệu riêng (class) Matrix (ma trận). Do ma trận cũng có các phép toán như phép cộng, phép nhân, bạn cũng muốn trực tiếp áp dụng các phép toán này cho object của lớp Matrix.

Khi này bạn sẽ cần sử dụng đến kỹ thuật nạp chồng toán tử.

Nạp chồng toán tử (operator overloading) là kỹ thuật định nghĩa các phép toán sẵn có trên kiểu dữ liệu tự tạo.

Giả sử bạn xây dựng kiểu dữ liệu riêng (class) Matrix (ma trận). Do ma trận cũng có các phép toán như phép cộng, phép nhân, bạn cũng muốn trực tiếp áp dụng các phép toán này cho object của lớp Matrix.

>>> a = 10
>>> a.__add__(10) # tương đương với gọi a + 10
20
>>> a + 10
20

Khi này bạn sẽ cần sử dụng đến kỹ thuật nạp chồng toán tử.

Nạp chồng toán tử (operator overloading) là kỹ thuật định nghĩa các phép toán sẵn có trên kiểu dữ liệu tự tạo.

Trong Python nạp chồng toán tử hoạt động tương đối khác với ngôn ngữ như C++/Java/C#. Các toán tử trong Python hoạt động dựa trên một số magic method.nạp chồng toán tử = ghi đè magic method tương ứng.

Ghi đè phương thức __new__()

Ghi đè phương thức __str__() và __repr__()nạp chồng phép toán tạo object. Đây chỉ là một ví dụ để bạn hiểu kỹ hơn về class, object và magic method trong Python. Trên thực tế bạn ít khi phải nạp chồng phép toán này.

Nạp chồng các phép toán số học

Giả sử bạn xây dựng kiểu dữ liệu riêng (class) Matrix (ma trận). Do ma trận cũng có các phép toán như phép cộng, phép nhân, bạn cũng muốn trực tiếp áp dụng các phép toán này cho object của lớp Matrix.

class Employee:
    def __new__(cls, *args, **kwargs):
        print('__new__ is being called')
        instance = object.__new__(cls)
        return instance

    def __init__(self, name: str):
        print('__init__ is being called')
        self.name = name

    def print(self):
        print(self.name)

if __name__ == '__main__':
    trump = Employee('Donald Trump')
    trump.print()
    putin = Employee('Vladimir Putin')    
    putin.print()

Khi này bạn sẽ cần sử dụng đến kỹ thuật nạp chồng toán tử.

Giả sử bạn xây dựng kiểu dữ liệu riêng (class) Matrix (ma trận). Do ma trận cũng có các phép toán như phép cộng, phép nhân, bạn cũng muốn trực tiếp áp dụng các phép toán này cho object của lớp Matrix.

__new__ is being called
__init__ is being called
Donald Trump
__new__ is being called
__init__ is being called
Vladimir Putin

Khi này bạn sẽ cần sử dụng đến kỹ thuật nạp chồng toán tử.

Giả sử bạn xây dựng kiểu dữ liệu riêng (class) Matrix (ma trận). Do ma trận cũng có các phép toán như phép cộng, phép nhân, bạn cũng muốn trực tiếp áp dụng các phép toán này cho object của lớp Matrix.

def __new__(cls, *args, **kwargs):
        print('__new__ is being called')
        instance = object.__new__(cls)
        return instance

Khi này bạn sẽ cần sử dụng đến kỹ thuật nạp chồng toán tử.

Nạp chồng toán tử (operator overloading) là kỹ thuật định nghĩa các phép toán sẵn có trên kiểu dữ liệu tự tạo.

Trong Python nạp chồng toán tử hoạt động tương đối khác với ngôn ngữ như C++/Java/C#. Các toán tử trong Python hoạt động dựa trên một số magic method.

Các phương thức ma thuật (magic method) trong Python là các phương thức đặc biệt bắt đầu và kết thúc bằng dấu gạch dưới kép. Chúng còn được gọi là các phương pháp dunder. Các phương thức ma thuật không có nghĩa là được bạn gọi trực tiếp, nhưng việc gọi này xảy ra trong nội bộ lớp trên một hành động nhất định.

Nạp chồng toán tử hoạt động dựa trên magic method. Vì vậy trước khi học cách nạp chồng toán tử, chúng ta cần hiểu thế nào là magic method trong Python.

Ghi đè phương thức __str__() và __repr__()

Nạp chồng các phép toán số học

Bài viết này đã giúp ích cho bạn?

Như bạn đã biết, Python định nghĩa sẵn một số phép toán trên các kiểu dữ liệu của mình. Ví dụ, phép cộng (+) đã được định nghĩa sẵn cho các kiểu số, kiểu xâu ký tự, kiểu danh sách.

Hãy xem ví dụ sau:

Ví dụ

class Vector:
    """A class for vector"""
    def __init__(self, x:float, y:float):
        self.x = x
        self.y = y
    def __str__(self):
        return f'({self.x}, {self.y})'
    def __repr__(self):
        return f'({self.x}, {self.y})'

Đây là ví dụ về một class Vector hai chiều đơn giản.

Thông thường, vector trong toán học hay được in ra ở dạng (x, y, z, ..). Chúng ta cũng muốn rằng khi dùng hàm print() trên object của Vector, kết quả in ra cũng có dạng (x, y).

Để làm việc này, chúng ta cần định nghĩa phương thức magic __str__() trong class Vector:

Ví dụ

def __str__(self):
    return f'({self.x}, {self.y})'

Đây là ví dụ về một class Vector hai chiều đơn giản.

Thông thường, vector trong toán học hay được in ra ở dạng (x, y, z, ..). Chúng ta cũng muốn rằng khi dùng hàm print() trên object của Vector, kết quả in ra cũng có dạng (x, y).

Để làm việc này, chúng ta cần định nghĩa phương thức magic __str__() trong class Vector:

Ví dụ

>>> v1 = Vector(0, 1); v2 = Vector(2, 3)
>>> print(v1)
(0, 1)
>>> print(v2)
(2, 3)

Đây là ví dụ về một class Vector hai chiều đơn giản.

Ví dụ

>>> v1 = Vector(1, 2)
>>> v1
<__main__.Vector object at 0x00000183425A2DC0>

Đây là ví dụ về một class Vector hai chiều đơn giản.

Ví dụ

def __repr__(self):
    return f'({self.x}, {self.y})'

Thông thường, vector trong toán học hay được in ra ở dạng (x, y, z, ..). Chúng ta cũng muốn rằng khi dùng hàm print() trên object của Vector, kết quả in ra cũng có dạng (x, y).

Để làm việc này, chúng ta cần định nghĩa phương thức magic __str__() trong class Vector:

Phương thức này cần trả về một chuỗi ký tự.

__str__() rất giống với phương thức ToString() trong C#.

Với class Vector như trên, bạn có thể sử dụng như sau:

Tuy nhiên, nếu chỉ có __str__(), khi bạn nhập lệnh:

Ví dụ

>>> a = 10
>>> a.__add__(10) # tương đương với gọi a + 10
20
>>> a + 10
20
0

Để giao diện tương tác cũng in ra kết quả như khi dùng hàm print(), bạn cần định nghĩa lại phương thức __repr__():

Ví dụ

>>> a = 10
>>> a.__add__(10) # tương đương với gọi a + 10
20
>>> a + 10
20
1

Phần thân __repr__() và __str__() cơ bản là giống nhau.

Nạp chồng các phép toán số học

Các phép toán số học +, -, *, / tương ứng với các magic method __add__(), __sub__(), __mul__(), __div__().

  • Phép toán + – (âm dương) tương ứng với __pos__() và __neg__().
  • Để nạp chồng các phép toán này, bạn cần định nghĩa/ghi đè magic method tương ứng.
  • Hãy xem ví dụ sau đây:
  • Với class Vector như trên bạn có thể thực hiện các phép toán cơ bản như sau:

Dưới đây là danh sách các hàm toán học cơ bản và magic method tương ứng của chúng