Descriptor

Lập trình Hướng đối tượng Nâng cao với Python

Jake Roach

Data Engineer

Thay đổi cách tương tác với thuộc tính

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn
# Tạo một đối tượng student và truy cập thuộc tính "ssn"
shaw = Student("Daniel Shaw", "193-80-1821")
print(shaw.ssn)

# Nếu giá trị bị thay đổi hoặc xóa thì sao? Xử lý thế nào?
193-80-1821
Lập trình Hướng đối tượng Nâng cao với Python

Tạo descriptor với @property

Descriptor là các đối tượng dùng để kiểm soát cách thuộc tính được lấy, gán, hoặc xóa

Tạo descriptor với @property

  • "getter", "setter", "deleter"
  • Tên phương thức == tên thuộc tính

Cũng có thể tạo descriptor bằng...

  • Hàm property()
  • __get__(), __set__(), __delete__()

$$

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn

    @property  
    def ssn(self):
        return "XXX-XX-" + self._ssn[-4:]

    @ssn.setter  
    def ssn(self, new_ssn):
        self._ssn = new_ssn 

    @ssn.deleter
    def ssn(self):
        raise AttributeError("Can't delete SSN")
Lập trình Hướng đối tượng Nâng cao với Python

@property

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn  # Does not need to include an underscore

    @property  
    def ssn(self):  # This is the "getter" method
        return "XXX-XX-" + self._ssn[-4:]
  • Kiểm soát cách lấy ssn
  • Làm việc với self._ssn, không phải self.ssn
Lập trình Hướng đối tượng Nâng cao với Python

@ssn.setter

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn
    ...

    @ssn.setter  
    def ssn(self, new_ssn):
        if len(new_ssn) == 11:
          # Add things such as data 
          # validation, operations on
          # other attributes, etc.
          self._ssn = new_ssn

@<attribute-name>.setter

  • Phương thức "setter" cho ssn
  • Kiểm tra chất lượng dữ liệu
  • Thực hiện thao tác trên thuộc tính khác

$$

$$

$$

Nhớ làm việc với self._ssn, không phải self.ssn!

Lập trình Hướng đối tượng Nâng cao với Python

@ssn.deleter

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn

    ...

    @ssn.deleter
    def ssn(self):
        # Can perform clean up, soft delete, raise exception
        raise AttributeError("Can't delete SSN")
Lập trình Hướng đối tượng Nâng cao với Python

Descriptor trong thực tế

shaw = Student("Daniel Shaw", "193-80-1821")
print(shaw.ssn)  # Access the ssn attribute
XXX-XX-1821
shaw.ssn = "821-11-9380"  # Update Shaw's social security number
print(shaw.ssn)
XXX-XX-9380
del shaw.ssn  # Attempt to delete the ssn attribute
AttributeError: Can't delete SSN
Lập trình Hướng đối tượng Nâng cao với Python

Ayo berlatih!

Lập trình Hướng đối tượng Nâng cao với Python

Preparing Video For Download...