Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Metaclasses trong Python
Metaclasses là một khái niệm nâng cao trong Python, thường không xuất hiện trong các tác vụ lập trình hằng ngày. Chúng được sử dụng để định nghĩa trạng thái của lớp, thay đổi thuộc tính, hoặc kiểm soát hành vi của các phương thức một cách chính xác.
Bài viết này sẽ giúp bạn hiểu cách tạo và sử dụng metaclasses trong Python.
Type và lập trình hướng đối tượng (OOP) trong Python
Trong Python, mọi thứ đều là một đối tượng, kể cả các lớp (class). Vì các lớp là đối tượng, chúng cũng cần được tạo ra bởi một lớp khác – gọi là metaclass.
Sơ đồ mối quan hệ:
Bài viết này được đăng tại [free tuts .net]
object --> class --> instance
Điều này có nghĩa là metaclass chính là lớp tạo ra các lớp khác. Thông thường, Python sử dụng type
làm metaclass mặc định, nhưng bạn cũng có thể tự định nghĩa metaclass với hành vi tùy chỉnh.
Hiểu hàm type()
trong Python
Để hiểu rõ hơn về metaclass, trước tiên cần nắm vững cách hoạt động của type()
.
Hàm type()
trong Python có hai mục đích chính:
Kiểm tra kiểu dữ liệu của biến
var = 12 print(type(var)) # <class 'int'>
Kiểm tra kiểu của một lớp (class)
class Foo: def bar(self): pass foo_obj = Foo() print(type(foo_obj)) # <class '__main__.Foo'> print(type(Foo)) # <class 'type'>
Ở đây, bạn sẽ thấy rằng:
foo_obj
là một thể hiện (instance) của lớpFoo
.- Nhưng
Foo
lại là một thể hiện củatype
. Điều này chứng minh rằng các lớp cũng được tạo ra từ một lớp khác, chính làtype
.
Tạo lớp động với type()
trong Python
Ngoài kiểm tra kiểu, type()
cũng có thể được sử dụng để tạo lớp động bằng cách truyền 3 tham số:
type(name: str, bases: tuple, attributes: dict)
name
: Tên lớp.bases
: Tuple chứa các lớp cha (nếu có).attributes
: Từ điển các thuộc tính và phương thức của lớp.
Ví dụ:
Dummy = type("Dummy", (), {"var1": "Xin chào"}) dummy = Dummy() print(dummy.var1) # Kết quả: Xin chào
Tạo metaclass trong Python
Metaclass có thể thay đổi hoặc kiểm tra lớp ngay khi nó được tạo. Để khai báo metaclass, bạn sử dụng tham số metaclass
khi định nghĩa lớp:
class LớpMới(metaclass=TênMetaclass): ...
Metaclass thường được triển khai bằng cách ghi đè phương thức __new__
.
Ví dụ:
class PrintAttributeMeta: def __new__(cls, class_name, bases, attributes): print("Các thuộc tính nhận được:", attributes) return type(class_name, bases, attributes) class Dummy(metaclass=PrintAttributeMeta): class_var1 = "Hello" class_var2 = 123
Kết quả:
Các thuộc tính nhận được: {'__module__': '__main__', '__qualname__': 'Dummy', 'class_var1': 'Hello', 'class_var2': 123}