Giới thiệu Python Descriptor
Giới thiệu
Các Python descriptors đã được gii thiệu trong Python 2.2, cùng với các lớp kiểu dáng mới,
nhưng chúng vẫn chưa được sử dụng rộng rãi. Các Python descriptors là cách để tạo ra các thuộc
tính được quản lý. Trong số rất nhiều lợi thế của chúng, các thuộc tính được quản lý đó được sử
dụng để bảo vmt thuộc tính khỏi nhng thay đổi hoặc để tự động cập nhật các giá trị của một
thuc tính phụ thuộc.
Các descriptors làm tăng sự hiểu biết về Python và ci thin các k năng mã hóa. Bài này giới
thiệu giao thức descriptors và trình bày cách tạo và sử dụng các descriptors.
Giao thức descriptors
Giao thức descriptors trong Python chỉ đơn giản là mt cách để xác định những gì sxảy ra khi
tham chiếu một thuộc tính trong mt mô hình. Nó cho phép mt lập trình viên quản truy cập
thuc tính dễ dàng và hiệu quả:
set
get
delete
Trong các ngôn ngữ lập trình khác, các descriptors được gọi là setter và getter, đây các hàm
public được sử dụng để Get (nhận giá trị) Set (đặt giá trị ) cho mt biến private. Python không
một khái niệm về các biến private và có th coi giao thức descriptors như là mt cách của
Python để đạt được điều tương tự.
Nhìn chung, một descriptor là mt thuộc tính của đối tượng với mt hành vi kết buộc, mt hành
vi mà việc truy cập thuộc tính của nó b ghi đè bằng các phương thức trong giao thức descriptors.
Các phương thức đó là __get__, __set____delete__. Nếu định nghĩa một phương thức bất
k trong số này cho mt đối tượng, người ta nói rằng đó là mt descriptor. Hãy xem xét kn
các phương thức này trong Liệt kê 1.
Liệt kê 1. Các phương thức descriptors
__get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance)
Ở đây:
__get__ truy cập thuộc tính. Nó trả về giá trị của thuộc tính hoặc đưa ra ngoại lệ
AttributeError nếu không tồn tại thuộc tính được yêu cầu.
__set__ được gọi là mt phép gán thuộc tính. Không trả vềi gì cả.
__delete__ kiểm soát hoạt động xóa. Không trả về cái gì cả.
Điều quan trọng cần lưu ý là các descriptors được gán cho một lớp, chkhông gán cho một
thcủa lớp. Việc sửa đổi lớp này sẽ ghi đè lên hoặc xóa chính descriptor đó, chứ không phải kích
hoạt mã của nó.
Về đầu trang
Khi nào cần các descriptors
Hãy xem xét mt thuộc tính email. Việc xác minh định dạng email đúng là cn thiết trước khi
gán mt giá trị cho thuộc tính đó. Descriptor này cho phép x đa chỉ email thông qua mt
biểu thức chính quy định dạng của nó được xác nhận hợp lệ trước khi gán cho một thuộc
tính.
Trong nhiều trường hợp khác, các giao thức descriptors trong Python kiểm soát truy cập đến các
thuc tính, chẳng hạn như bảo vệ thuộc tính name.
Về đầu trang
Tạo các descriptors
Bạn có th tạo ra một descriptor theo mt s cách sau:
Tạo mt lớp và ghi đè lên bất kỳ các phương thức nào của descriptor: __set__, __
get__ và __delete__. Phương thức này được sử dụng khi cần descriptor ging nhau qua
nhiều lớp và các thuc tính khác nhau, ví dụ, để xác nhn hợp lệ cho kiểu.
Sử dụng một kiểu property (đặc tính) là một cách đơn giản hơn và linh hoạt hơn để tạo ra
mt descriptor.
Sử dụng sức mạnh của các bộ trang t đặc tính, là mt tổ hợp của phương thức về kiểu
đặc tính và các bộ trang t của Python.
Tất cả các ví dụ dưới đây là ging nhau theo quan đim hoạt động. Sự khác biệt nằm ở việc thực
hiện.
Về đầu trang
Tạo các descriptors bng cách sử dụng các phương thức lớp
Liệt kê 2 cho thấy tính đơn giản của việc kiểm soát gán thuộc tính trong Python.
Liệt kê 2. Tạo các descriptors bằng cách sử dụng các phương thức lớp
class Descriptor(object):
def __init__(self):
self._name = ''
def __get__(self, instance, owner):
print "Getting: %s" % self._name
return self._name
def __set__(self, instance, name):
print "Setting: %s" % name
self._name = name.title()
def __delete__(self, instance):
print "Deleting: %s" %self._name
del self._name
class Person(object):
name = Descriptor()
Hãy sử dụng mã này và xem kết quả ban đầu:
>>> user = Person()
>>> user.name = 'john smith'
Setting: john smith
>>> user.name
Getting: John Smith
'John Smith'
>>> del user.name
Deleting: John Smith
Một lớp descriptor được tạo ra bằng cách ghi đè các phương thức __set__(), __get__()
__delete__() của lớp cha msao cho
get sẽ in ra Getting
delete sin ra Deleting
set sẽ in ra Setting
thay đi giá trị thuộc tính thành tiêu đề (viết hoa chcái đầu tiên, viết thường các chữ khác)
trước khi gán. Vic này rất tin dụng, chng hạn khi lưu và in các tên.
Vic chuyển đổi thành chữ hoa cũng có thể được chuyển sang cho phương thức __get__().
_value sẽ có giá trị ban đầu và sẽ được chuyển đổi thành tiêu đề khi yêu cầu get.
Về đầu trang
Tạo các descriptors bằng cách sử dụng kiểu property