Thuộc tính set được sử dụng để làm gì trong python?

Với Python, bạn có thể tạo các thuộc tính được quản lý trong các lớp của mình. Bạn có thể sử dụng các thuộc tính được quản lý, còn được gọi là thuộc tính, khi bạn cần sửa đổi triển khai nội bộ của chúng mà không thay đổi API công khai của lớp. Việc cung cấp các API ổn định có thể giúp bạn tránh vi phạm mã của người dùng khi họ dựa vào các lớp và đối tượng của bạn

Show

Các thuộc tính được cho là cách phổ biến nhất để tạo các thuộc tính được quản lý một cách nhanh chóng và theo phong cách Pythonic thuần túy nhất

Trong hướng dẫn này, bạn sẽ học cách

  • Tạo các thuộc tính hoặc thuộc tính được quản lý trong các lớp học của bạn
  • Thực hiện đánh giá thuộc tính lười biếng và cung cấp các thuộc tính được tính toán
  • Tránh các phương thức setter và getter để làm cho các lớp của bạn giống Pythonic hơn
  • Tạo các thuộc tính chỉ đọc, chỉ đọc và chỉ ghi
  • Tạo các API nhất quán và tương thích ngược cho các lớp của bạn

Bạn cũng sẽ viết một vài ví dụ thực tế sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 để xác thực dữ liệu đầu vào, tính toán các giá trị thuộc tính một cách linh hoạt, ghi nhật ký mã của bạn, v.v. Để tận dụng tối đa hướng dẫn này, bạn nên biết kiến ​​thức cơ bản về lập trình hướng đối tượng và trình trang trí trong Python

Tiền thưởng miễn phí. 5 Suy nghĩ về Làm chủ Python, một khóa học miễn phí dành cho các nhà phát triển Python cho bạn thấy lộ trình và tư duy mà bạn sẽ cần để đưa các kỹ năng Python của mình lên một tầm cao mới

Quản lý thuộc tính trong lớp học của bạn

Khi bạn định nghĩa một lớp trong ngôn ngữ lập trình hướng đối tượng, có thể bạn sẽ kết thúc với một số thể hiện và lớp. Nói cách khác, bạn sẽ nhận được các biến có thể truy cập thông qua thể hiện, lớp hoặc thậm chí cả hai, tùy thuộc vào ngôn ngữ. Các thuộc tính đại diện hoặc giữ trạng thái bên trong của một đối tượng nhất định mà bạn sẽ thường xuyên cần truy cập và thay đổi

Thông thường, bạn có ít nhất hai cách để quản lý một thuộc tính. Bạn có thể truy cập và thay đổi thuộc tính trực tiếp hoặc bạn có thể sử dụng các phương thức. Phương thức là các chức năng gắn liền với một lớp nhất định. Chúng cung cấp các hành vi và hành động mà một đối tượng có thể thực hiện với dữ liệu và thuộc tính bên trong của nó

Nếu bạn hiển thị các thuộc tính của mình cho người dùng, thì chúng sẽ trở thành một phần của API công khai của các lớp của bạn. Người dùng của bạn sẽ truy cập và thay đổi chúng trực tiếp trong mã của họ. Sự cố xảy ra khi bạn cần thay đổi cách triển khai nội bộ của một thuộc tính nhất định

Giả sử bạn đang làm việc trên lớp

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6. Việc triển khai ban đầu có một thuộc tính duy nhất được gọi là
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7. Bạn hoàn thành mã hóa lớp và cung cấp lớp đó cho người dùng cuối của bạn. Họ bắt đầu sử dụng
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 trong mã của mình để tạo ra nhiều dự án và ứng dụng tuyệt vời. Làm tốt lắm

Bây giờ, giả sử rằng bạn có một người dùng quan trọng đến gặp bạn với một yêu cầu mới. Họ không muốn

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 lưu trữ bán kính nữa. Họ cần một thuộc tính
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 công khai

Tại thời điểm này, việc xóa

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 để bắt đầu sử dụng
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 có thể phá vỡ mã của một số người dùng cuối của bạn. Bạn cần quản lý tình huống này theo một cách khác ngoài việc loại bỏ
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7

Các ngôn ngữ lập trình như Java và C++ khuyến khích bạn không bao giờ để lộ các thuộc tính của mình để tránh loại vấn đề này. Thay vào đó, bạn nên cung cấp các phương thức getter và setter, còn được gọi là bộ truy cập và bộ biến đổi, tương ứng. Các phương pháp này cung cấp một cách để thay đổi cách triển khai nội bộ các thuộc tính của bạn mà không cần thay đổi API công khai của bạn

Ghi chú. Các phương thức getter và setter thường được coi là phản mẫu và là tín hiệu của thiết kế hướng đối tượng kém. Đối số chính đằng sau đề xuất này là các phương thức này phá vỡ sự đóng gói. Chúng cho phép bạn truy cập và thay đổi các thành phần của đối tượng của bạn

Cuối cùng, những ngôn ngữ này cần các phương thức getter và setter vì chúng không cung cấp cách phù hợp để thay đổi cách triển khai bên trong của một thuộc tính nếu một yêu cầu nhất định thay đổi. Việc thay đổi triển khai nội bộ sẽ yêu cầu sửa đổi API, điều này có thể phá vỡ mã của người dùng cuối của bạn

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

Phương pháp Getter và Setter trong Python

Về mặt kỹ thuật, không có gì ngăn cản bạn sử dụng getter và setter trong Python. Đây là cách tiếp cận này sẽ trông như thế nào

# point.py

class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y

    def get_x(self):
        return self._x

    def set_x(self, value):
        self._x = value

    def get_y(self):
        return self._y

    def set_y(self, value):
        self._y = value

Trong ví dụ này, bạn tạo

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 với hai thuộc tính không công khai là
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
5 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
6 để giữ tọa độ Descartes của điểm trong tầm tay

Ghi chú. Python không có khái niệm về công cụ sửa đổi truy cập, chẳng hạn như

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
7,
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
8 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
9, để hạn chế quyền truy cập vào các thuộc tính và phương thức. Trong Python, sự khác biệt là giữa các thành viên lớp công khai và không công khai

Nếu bạn muốn báo hiệu rằng một thuộc tính hoặc phương thức đã cho là không công khai, thì bạn phải sử dụng Python nổi tiếng để thêm tiền tố vào tên bằng dấu gạch dưới (

>>> class Circle:
..     def __init__(self, radius):
..         self._radius = radius
..     radius = property(lambda self: self._radius)
...

>>> circle = Circle(42.0)
>>> circle.radius
42.0
0). Đó là lý do đằng sau việc đặt tên cho các thuộc tính
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
5 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
6

Lưu ý rằng đây chỉ là một quy ước. Nó không ngăn bạn và các lập trình viên khác truy cập các thuộc tính bằng cách sử dụng ký hiệu dấu chấm, như trong

>>> class Circle:
..     def __init__(self, radius):
..         self._radius = radius
..     radius = property(lambda self: self._radius)
...

>>> circle = Circle(42.0)
>>> circle.radius
42.0
3. Tuy nhiên, đó là thực tế xấu để vi phạm quy ước này

Để truy cập và thay đổi giá trị của

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
5 hoặc
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
6, bạn có thể sử dụng các phương thức getter và setter tương ứng. Hãy tiếp tục và lưu định nghĩa ở trên của
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 trong một mô-đun Python và nhập lớp vào trình bao tương tác của bạn

Đây là cách bạn có thể làm việc với

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 trong mã của mình

>>>

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5

Với

>>> class Circle:
..     def __init__(self, radius):
..         self._radius = radius
..     radius = property(lambda self: self._radius)
...

>>> circle = Circle(42.0)
>>> circle.radius
42.0
8 và
>>> class Circle:
..     def __init__(self, radius):
..         self._radius = radius
..     radius = property(lambda self: self._radius)
...

>>> circle = Circle(42.0)
>>> circle.radius
42.0
9, bạn có thể truy cập các giá trị hiện tại của
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
5 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
6. Bạn có thể sử dụng phương thức setter để lưu trữ một giá trị mới trong thuộc tính được quản lý tương ứng. Từ mã này, bạn có thể xác nhận rằng Python không hạn chế quyền truy cập vào các thuộc tính không công khai. Bạn có làm như vậy hay không là tùy thuộc vào bạn

Phương pháp tiếp cận Pythonic

Mặc dù ví dụ bạn vừa thấy sử dụng phong cách mã hóa Python, nhưng nó không giống Pythonic. Trong ví dụ này, các phương thức getter và setter không thực hiện thêm bất kỳ xử lý nào với

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
5 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
6. Bạn có thể viết lại
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 theo cách ngắn gọn và Pythonic hơn

>>>

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42

Mã này phát hiện ra một nguyên tắc cơ bản. Việc hiển thị các thuộc tính cho người dùng cuối là bình thường và phổ biến trong Python. Bạn không cần phải làm lộn xộn các lớp của mình với các phương thức getter và setter mọi lúc, điều này nghe có vẻ khá thú vị. Tuy nhiên, làm thế nào bạn có thể xử lý các thay đổi yêu cầu dường như liên quan đến thay đổi API?

Không giống như Java và C++, Python cung cấp các công cụ tiện dụng cho phép bạn thay đổi cách triển khai cơ bản của các thuộc tính mà không cần thay đổi API công khai của bạn. Cách tiếp cận phổ biến nhất là biến thuộc tính của bạn thành thuộc tính

Ghi chú. Một cách tiếp cận phổ biến khác để cung cấp các thuộc tính được quản lý là sử dụng các bộ mô tả. Tuy nhiên, trong hướng dẫn này, bạn sẽ tìm hiểu về các thuộc tính

Các thuộc tính đại diện cho một chức năng trung gian giữa một thuộc tính đơn giản (hoặc trường) và một phương thức. Nói cách khác, chúng cho phép bạn tạo các phương thức hoạt động giống như các thuộc tính. Với các thuộc tính, bạn có thể thay đổi cách tính toán thuộc tính đích bất cứ khi nào bạn cần

Ví dụ: bạn có thể biến cả

>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 thành thuộc tính. Với thay đổi này, bạn có thể tiếp tục truy cập chúng dưới dạng thuộc tính. Bạn cũng sẽ có một phương pháp cơ bản giữ
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 sẽ cho phép bạn sửa đổi triển khai nội bộ của chúng và thực hiện hành động đối với chúng ngay trước khi người dùng của bạn truy cập và thay đổi chúng

Ghi chú. Các thuộc tính không dành riêng cho Python. Các ngôn ngữ như JavaScript, C#, Kotlin và các ngôn ngữ khác cũng cung cấp các công cụ và kỹ thuật để tạo các thuộc tính với tư cách là thành viên của lớp

Ưu điểm chính của các thuộc tính Python là chúng cho phép bạn hiển thị các thuộc tính của mình như một phần của API công khai. Nếu bạn cần thay đổi triển khai cơ bản, thì bạn có thể biến thuộc tính thành thuộc tính bất kỳ lúc nào mà không gặp nhiều khó khăn

Trong các phần sau, bạn sẽ tìm hiểu cách tạo thuộc tính trong Python

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

Bắt đầu với # circle.py class Circle: def __init__(self, radius): self._radius = radius def _get_radius(self): print("Get radius") return self._radius def _set_radius(self, value): print("Set radius") self._radius = value def _del_radius(self): print("Delete radius") del self._radius radius = property( fget=_get_radius, fset=_set_radius, fdel=_del_radius, doc="The radius property." ) 4 của Python

Python là cách Pythonic để tránh các phương thức getter và setter chính thức trong mã của bạn. Chức năng này cho phép bạn chuyển thành thuộc tính hoặc thuộc tính được quản lý. Vì

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là một chức năng tích hợp sẵn nên bạn có thể sử dụng nó mà không cần nhập bất cứ thứ gì. Ngoài ra,
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là để đảm bảo hiệu suất tối ưu

Ghi chú. Người ta thường coi

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là một chức năng tích hợp sẵn. Tuy nhiên,
@decorator
def func(a):
    return a
4 là một lớp được thiết kế để hoạt động như một chức năng hơn là một lớp thông thường. Đó là lý do tại sao hầu hết các nhà phát triển Python gọi nó là một chức năng. Đó cũng là lý do tại sao
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 không tuân theo quy ước Python cho

Hướng dẫn này tuân theo các phương pháp phổ biến là gọi

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 một hàm chứ không phải một lớp. Tuy nhiên, trong một số phần, bạn sẽ thấy nó được gọi là một lớp để thuận tiện cho việc giải thích

Với

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4, bạn có thể đính kèm các phương thức getter và setter cho các thuộc tính lớp đã cho. Bằng cách này, bạn có thể xử lý việc triển khai nội bộ cho thuộc tính đó mà không để lộ các phương thức getter và setter trong API của mình. Bạn cũng có thể chỉ định cách xử lý việc xóa thuộc tính và cung cấp chuỗi tài liệu phù hợp cho thuộc tính của mình

Đây là chữ ký đầy đủ của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4

property(fget=None, fset=None, fdel=None, doc=None)

Hai đối số đầu tiên nhận các đối tượng hàm sẽ đóng vai trò của các phương thức getter (

@decorator
def func(a):
    return a
9) và setter (
def func(a):
    return a

func = decorator(func)
0). Đây là một bản tóm tắt về những gì mỗi đối số làm

Đối số Mô tả_______41_______9Hàm trả về giá trị của thuộc tính được quản lý

def func(a):
    return a

func = decorator(func)
0Hàm cho phép bạn đặt giá trị của thuộc tính được quản lý
def func(a):
    return a

func = decorator(func)
3Hàm xác định cách thuộc tính được quản lý xử lý việc xóa
def func(a):
    return a

func = decorator(func)
4Chuỗi đại diện cho chuỗi tài liệu của thuộc tính

Giá trị trả về của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 chính là thuộc tính được quản lý. Nếu bạn truy cập thuộc tính được quản lý, chẳng hạn như trong
def func(a):
    return a

func = decorator(func)
6, thì Python sẽ tự động gọi
def func(a):
    return a

func = decorator(func)
7. Nếu bạn gán một giá trị mới cho thuộc tính, chẳng hạn như trong
def func(a):
    return a

func = decorator(func)
8, thì Python sẽ gọi
def func(a):
    return a

func = decorator(func)
9 bằng cách sử dụng giá trị đầu vào
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
00 làm đối số. Cuối cùng, nếu bạn chạy một câu lệnh
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
01, thì Python sẽ tự động gọi
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
02

Ghi chú. Ba đối số đầu tiên của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 nhận các đối tượng hàm. Bạn có thể coi một đối tượng hàm là tên hàm mà không cần gọi cặp dấu ngoặc đơn

Bạn có thể sử dụng

def func(a):
    return a

func = decorator(func)
4 để cung cấp chuỗi tài liệu thích hợp cho tài sản của mình. Bạn và các lập trình viên đồng nghiệp của bạn sẽ có thể đọc chuỗi tài liệu đó bằng Python. Đối số
def func(a):
    return a

func = decorator(func)
4 cũng hữu ích khi bạn đang làm việc với trình soạn thảo mã và IDE hỗ trợ truy cập chuỗi tài liệu

Bạn có thể sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 làm chức năng hoặc công cụ trang trí để xây dựng thuộc tính của mình. Trong hai phần sau, bạn sẽ học cách sử dụng cả hai phương pháp. Tuy nhiên, bạn nên biết trước rằng phương pháp trang trí phổ biến hơn trong cộng đồng Python

Tạo thuộc tính với # circle.py class Circle: def __init__(self, radius): self._radius = radius def _get_radius(self): print("Get radius") return self._radius def _set_radius(self, value): print("Set radius") self._radius = value def _del_radius(self): print("Delete radius") del self._radius radius = property( fget=_get_radius, fset=_set_radius, fdel=_del_radius, doc="The radius property." ) 4

Bạn có thể tạo một thuộc tính bằng cách gọi

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 với một tập hợp các đối số thích hợp và gán giá trị trả về của nó cho một thuộc tính lớp. Tất cả các đối số cho
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là tùy chọn. Tuy nhiên, bạn thường cung cấp ít nhất một hàm setter

Ví dụ sau đây cho thấy cách tạo một lớp

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 với một thuộc tính tiện dụng để quản lý bán kính của nó

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )

Trong đoạn mã này, bạn tạo

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6. Trình khởi tạo lớp,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
13, nhận ____24_______14 làm đối số và lưu trữ nó trong một thuộc tính không công khai có tên là ____
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
15. Sau đó, bạn xác định ba phương pháp không công khai

  1. >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    16 trả về giá trị hiện tại của
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    15
  2. >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    18 lấy
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    00 làm đối số và gán nó cho
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    15
  3. >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    21 xóa thuộc tính thể hiện
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    15

Khi bạn đã có ba phương thức này, bạn tạo một thuộc tính lớp có tên là

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 để lưu trữ đối tượng thuộc tính. Để khởi tạo thuộc tính, bạn chuyển ba phương thức làm đối số cho
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4. Bạn cũng chuyển một chuỗi tài liệu phù hợp cho thuộc tính của mình

Trong ví dụ này, bạn sử dụng để cải thiện khả năng đọc mã và tránh nhầm lẫn. Bằng cách đó, bạn biết chính xác phương thức nào đi vào từng đối số

Để dùng thử

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6, hãy chạy đoạn mã sau trong trình bao Python của bạn

>>>

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.

Thuộc tính

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 ẩn thuộc tính phiên bản không công khai
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
15, hiện là thuộc tính được quản lý của bạn trong ví dụ này. Bạn có thể truy cập và chỉ định trực tiếp
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7. Trong nội bộ, Python tự động gọi
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
16 và
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
18 khi cần. Khi bạn thực thi
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
31, Python gọi
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
21, thao tác này sẽ xóa
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
15 bên dưới

Sử dụng Hàm

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
34 làm Phương thức GetterHiển thị/Ẩn

Bên cạnh việc sử dụng các hàm được đặt tên thông thường để cung cấp các phương thức getter trong các thuộc tính của bạn, bạn cũng có thể sử dụng các hàm

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
34

Đây là phiên bản của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 trong đó thuộc tính
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 sử dụng hàm
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
34 làm phương thức getter của nó

>>>

>>> class Circle:
..     def __init__(self, radius):
..         self._radius = radius
..     radius = property(lambda self: self._radius)
...

>>> circle = Circle(42.0)
>>> circle.radius
42.0

Nếu chức năng của phương thức getter của bạn bị giới hạn chỉ trả về giá trị hiện tại của thuộc tính được quản lý, thì sử dụng hàm

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
34 có thể là một cách tiếp cận hữu ích

Thuộc tính là thuộc tính lớp quản lý thuộc tính thể hiện. Bạn có thể coi một thuộc tính là một tập hợp các phương thức được kết hợp với nhau. Nếu bạn kiểm tra cẩn thận

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7, thì bạn có thể tìm thấy các phương thức thô mà bạn đã cung cấp dưới dạng các đối số
@decorator
def func(a):
    return a
9,
def func(a):
    return a

func = decorator(func)
0 và
def func(a):
    return a

func = decorator(func)
3

>>>

>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]

Bạn có thể truy cập các phương thức getter, setter và deleter trong một thuộc tính nhất định thông qua các phương thức tương ứng

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
44,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
45 và
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
46

Các thuộc tính cũng ghi đè các mô tả. Nếu bạn sử dụng để kiểm tra các thành viên nội bộ của một tài sản nhất định, thì bạn sẽ tìm thấy

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
48 và
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
49 trong danh sách. Các phương pháp này cung cấp một cài đặt mặc định của

Ghi chú. Nếu bạn muốn hiểu rõ hơn về việc triển khai nội bộ của

@decorator
def func(a):
    return a
4 với tư cách là một lớp, hãy xem phần mô tả trong tài liệu

Ví dụ: triển khai mặc định của

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
48 sẽ chạy khi bạn không cung cấp phương thức thiết lập tùy chỉnh. Trong trường hợp này, bạn nhận được một
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
53 vì không có cách nào để đặt thuộc tính cơ bản

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

Sử dụng # circle.py class Circle: def __init__(self, radius): self._radius = radius def _get_radius(self): print("Get radius") return self._radius def _set_radius(self, value): print("Set radius") self._radius = value def _del_radius(self): print("Delete radius") del self._radius radius = property( fget=_get_radius, fset=_set_radius, fdel=_del_radius, doc="The radius property." ) 4 làm Trang trí

Trang trí ở khắp mọi nơi trong Python. Chúng là các hàm lấy một hàm khác làm đối số và trả về một hàm mới với chức năng được thêm vào. Với một trình trang trí, bạn có thể đính kèm các thao tác trước và sau xử lý vào một chức năng hiện có

Khi giới thiệu

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4, cú pháp trang trí không khả dụng. Cách duy nhất để xác định các thuộc tính là chuyển các phương thức getter, setter và deleter, như bạn đã học trước đây. Cú pháp trang trí đã được thêm vào và ngày nay, sử dụng
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 làm công cụ trang trí là phương pháp phổ biến nhất trong cộng đồng Python

Cú pháp trang trí bao gồm việc đặt tên của hàm trang trí với ký hiệu

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
57 ở đầu ngay trước định nghĩa của hàm bạn muốn trang trí

@decorator
def func(a):
    return a

Trong đoạn mã này,

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
58 có thể là một hàm hoặc lớp nhằm trang trí cho
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
59. Cú pháp này tương đương như sau

def func(a):
    return a

func = decorator(func)

Dòng mã cuối cùng gán lại tên

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
60 để giữ kết quả của việc gọi
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
61. Lưu ý rằng đây là cú pháp giống như bạn đã sử dụng để tạo thuộc tính trong phần trên

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 của Python cũng có thể hoạt động như một công cụ trang trí, vì vậy bạn có thể sử dụng cú pháp
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
63 để tạo các thuộc tính của mình một cách nhanh chóng

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
0

Mã này trông khá khác so với cách tiếp cận phương thức getter và setter.

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 bây giờ trông Pythonic và sạch sẽ hơn. Bạn không cần sử dụng các tên phương thức như
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
16,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
18 và
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
21 nữa. Bây giờ bạn có ba phương thức có cùng tên giống như thuộc tính rõ ràng và mô tả. Làm thế nào là có thể?

Phương pháp trang trí để tạo thuộc tính yêu cầu xác định phương thức đầu tiên sử dụng tên công khai cho thuộc tính được quản lý cơ bản, trong trường hợp này là

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7. Phương pháp này sẽ thực hiện logic getter. Trong ví dụ trên, dòng 7 đến dòng 11 thực hiện phương thức đó

Dòng 13 đến 16 xác định phương thức setter cho

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7. Trong trường hợp này, cú pháp khá khác. Thay vì sử dụng lại
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
63, bạn sử dụng
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
71. Tại sao bạn cần phải làm điều đó?

>>>

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
1

Bên cạnh

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
44,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
45,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
46 và một loạt các thuộc tính và phương thức đặc biệt khác,
@decorator
def func(a):
    return a
4 cũng cung cấp
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
77,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
78 và
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
79. Ba phương thức này đều trả về một thuộc tính mới

Khi bạn trang trí phương thức

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
80 thứ hai với
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
71 (dòng 13), bạn tạo một thuộc tính mới và gán lại tên cấp độ lớp
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 (dòng 8) để giữ nó. Thuộc tính mới này chứa cùng một tập hợp các phương thức của thuộc tính ban đầu ở dòng 8 với việc bổ sung phương thức setter mới được cung cấp ở dòng 14. Cuối cùng, cú pháp trang trí gán lại thuộc tính mới cho tên cấp lớp
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7

Cơ chế xác định phương thức deleter cũng tương tự. Lần này, bạn cần sử dụng công cụ trang trí

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
84. Khi kết thúc quá trình, bạn nhận được một thuộc tính chính thức với các phương thức getter, setter và deleter

Cuối cùng, làm thế nào bạn có thể cung cấp các chuỗi tài liệu phù hợp cho các thuộc tính của mình khi bạn sử dụng phương pháp trang trí?

Việc triển khai

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 mới hoạt động giống như ví dụ trong phần trên

>>>

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.

Bạn không cần sử dụng cặp dấu ngoặc đơn để gọi phương thức

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
80. Thay vào đó, bạn có thể truy cập vào
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 như cách bạn truy cập vào một thuộc tính thông thường, đây là mục đích sử dụng chính của các thuộc tính. Chúng cho phép bạn coi các phương thức là thuộc tính và chúng đảm nhiệm việc tự động gọi tập phương thức cơ bản

Dưới đây là bản tóm tắt một số điểm quan trọng cần nhớ khi bạn tạo các thuộc tính bằng phương pháp trang trí

  • Trình trang trí
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    63 phải trang trí phương thức getter
  • Chuỗi tài liệu phải đi theo phương thức getter
  • Các phương thức setter và deleter phải được trang trí bằng tên của phương thức getter cộng với
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    90 và
    >>> from point import Point
    
    >>> point = Point(12, 5)
    >>> point.get_x()
    12
    >>> point.get_y()
    5
    
    >>> point.set_x(42)
    >>> point.get_x()
    42
    
    >>> # Non-public attributes are still accessible
    >>> point._x
    42
    >>> point._y
    5
    
    91, tương ứng

Cho đến thời điểm này, bạn đã tạo các thuộc tính được quản lý bằng cách sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 làm chức năng và làm công cụ trang trí. Nếu bạn kiểm tra các triển khai
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 của mình cho đến nay, thì bạn sẽ lưu ý rằng các phương thức getter và setter của chúng không thêm bất kỳ xử lý bổ sung thực sự nào vào đầu các thuộc tính của bạn

Nói chung, bạn nên tránh biến các thuộc tính không cần xử lý thêm thành các thuộc tính. Sử dụng các thuộc tính trong những tình huống đó có thể làm cho mã của bạn

  • Dài dòng không cần thiết
  • Gây nhầm lẫn cho các nhà phát triển khác
  • Chậm hơn mã dựa trên các thuộc tính thông thường

Trừ khi bạn cần thứ gì đó hơn là quyền truy cập thuộc tính trần, đừng viết thuộc tính. Chúng làm lãng phí thời gian của CPU và quan trọng hơn, chúng làm lãng phí thời gian của bạn. Cuối cùng, bạn nên tránh viết các phương thức getter và setter rõ ràng và sau đó gói chúng trong một thuộc tính. Thay vào đó, hãy sử dụng trình trang trí

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
63. Đó hiện là cách Pythonic nhất để đi

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

Cung cấp các thuộc tính chỉ đọc

Có lẽ trường hợp sử dụng cơ bản nhất của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là cung cấp các thuộc tính chỉ đọc trong các lớp học của bạn. Giả sử bạn cần một lớp
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 không cho phép người dùng thay đổi giá trị ban đầu của tọa độ của nó,
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
97 và
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
98. Để đạt được mục tiêu này, bạn có thể tạo
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 như trong ví dụ sau

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
3

Tại đây, bạn lưu trữ các đối số đầu vào trong các thuộc tính

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
5 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
6. Như bạn đã biết, việc sử dụng dấu gạch dưới ở đầu (
>>> class Circle:
..     def __init__(self, radius):
..         self._radius = radius
..     radius = property(lambda self: self._radius)
...

>>> circle = Circle(42.0)
>>> circle.radius
42.0
0) trong tên sẽ cho các nhà phát triển khác biết rằng chúng là thuộc tính không công khai và không nên truy cập bằng cách sử dụng ký hiệu dấu chấm, chẳng hạn như trong
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
03. Cuối cùng, bạn xác định hai phương thức getter và trang trí chúng bằng
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
63

Bây giờ bạn có hai thuộc tính chỉ đọc,

>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6, làm tọa độ của bạn

>>>

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
4

Ở đây,

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
07 và
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
08 là những ví dụ cơ bản về thuộc tính chỉ đọc. Hành vi của họ dựa trên mô tả cơ bản mà
@decorator
def func(a):
    return a
4 cung cấp. Như bạn đã thấy, việc triển khai
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
48 mặc định sẽ tăng
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
53 khi bạn không xác định phương thức setter thích hợp

Bạn có thể thực hiện triển khai

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 này xa hơn một chút và cung cấp các phương thức thiết lập rõ ràng để đưa ra một ngoại lệ tùy chỉnh với các thông báo cụ thể và phức tạp hơn

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
5

Trong ví dụ này, bạn xác định một ngoại lệ tùy chỉnh có tên là

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
13. Ngoại lệ này cho phép bạn tùy chỉnh cách triển khai lớp
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 bất biến của mình. Bây giờ, cả hai phương thức setter đều tăng ngoại lệ tùy chỉnh của bạn bằng một thông báo rõ ràng hơn. Hãy tiếp tục và thử dùng
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 đã được cải thiện của bạn

Tạo thuộc tính đọc-ghi

Bạn cũng có thể sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 để cung cấp các thuộc tính được quản lý với khả năng đọc-ghi. Trong thực tế, bạn chỉ cần cung cấp phương thức getter (“read”) và phương thức setter (“write”) thích hợp cho các thuộc tính của mình để tạo các thuộc tính được quản lý đọc-ghi

Giả sử bạn muốn lớp

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 của mình có thuộc tính
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0. Tuy nhiên, việc lấy bán kính và đường kính trong trình khởi tạo lớp dường như không cần thiết vì bạn có thể tính toán cái này bằng cách sử dụng cái kia. Đây là một
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 quản lý
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 dưới dạng thuộc tính đọc-ghi

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
6

Ở đây, bạn tạo một lớp

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 với một lớp
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 đọc-ghi. Trong trường hợp này, phương thức getter chỉ trả về giá trị bán kính. Phương thức setter chuyển đổi giá trị đầu vào cho bán kính và gán nó cho biến không công khai
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
15, là biến bạn sử dụng để lưu trữ dữ liệu cuối cùng

Có một chi tiết tinh tế cần lưu ý trong triển khai mới này của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 và thuộc tính
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 của nó. Trong trường hợp này, trình khởi tạo lớp gán trực tiếp giá trị đầu vào cho thuộc tính
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 thay vì lưu trữ nó trong một thuộc tính không công khai chuyên dụng, chẳng hạn như
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
15

Tại sao?

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 cũng triển khai thuộc tính
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 làm thuộc tính. Phương thức getter tính toán đường kính bằng bán kính. Phương thức setter làm điều gì đó tò mò. Thay vì lưu trữ đường kính đầu vào
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
00 trong một thuộc tính chuyên dụng, nó sẽ tính toán bán kính và ghi kết quả vào
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7

Đây là cách hoạt động của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 của bạn

>>>

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
7

Cả

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 và
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 đều hoạt động như các thuộc tính bình thường trong các ví dụ này, cung cấp một API công khai Pythonic rõ ràng cho lớp
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 của bạn

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

Cung cấp các thuộc tính chỉ ghi

Bạn cũng có thể tạo các thuộc tính chỉ ghi bằng cách điều chỉnh cách bạn triển khai phương thức getter cho các thuộc tính của mình. Ví dụ: bạn có thể làm cho phương thức getter của mình đưa ra một ngoại lệ mỗi khi người dùng truy cập giá trị thuộc tính cơ bản

Đây là một ví dụ về xử lý mật khẩu với thuộc tính chỉ ghi

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
8

Trình khởi tạo của

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
37 lấy tên người dùng và mật khẩu làm đối số và lưu trữ chúng trong
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
38 và
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
39, tương ứng. Bạn sử dụng một thuộc tính để quản lý cách lớp của bạn xử lý mật khẩu đầu vào. Phương thức getter tăng
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
53 bất cứ khi nào người dùng cố truy xuất mật khẩu hiện tại. Điều này biến
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
39 thành thuộc tính chỉ ghi

>>>

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
9

Trong ví dụ này, bạn tạo

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
42 dưới dạng phiên bản
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
37 với mật khẩu ban đầu. Phương thức setter băm mật khẩu và lưu trữ nó trong
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
44. Lưu ý rằng khi bạn cố gắng truy cập trực tiếp vào
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
39, bạn sẽ nhận được một
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
53. Cuối cùng, việc gán một giá trị mới cho
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
39 sẽ kích hoạt phương thức setter và tạo một mật khẩu băm mới

Trong phương thức setter của

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
39, bạn sử dụng
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
49 để tạo một chuỗi ngẫu nhiên 32 byte làm muối của hàm băm của bạn. Để tạo mật khẩu băm, bạn sử dụng. Sau đó, bạn lưu trữ mật khẩu được băm trong thuộc tính không công khai
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
44. Làm như vậy đảm bảo rằng bạn không bao giờ lưu mật khẩu văn bản gốc trong bất kỳ thuộc tính có thể truy xuất nào

Đưa # circle.py class Circle: def __init__(self, radius): self._radius = radius def _get_radius(self): print("Get radius") return self._radius def _set_radius(self, value): print("Set radius") self._radius = value def _del_radius(self): print("Delete radius") del self._radius radius = property( fget=_get_radius, fset=_set_radius, fdel=_del_radius, doc="The radius property." ) 4 của Python vào hoạt động

Cho đến giờ, bạn đã học cách sử dụng hàm có sẵn

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 của Python để tạo các thuộc tính được quản lý trong các lớp của mình. Bạn đã sử dụng
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 làm chức năng và trang trí, đồng thời tìm hiểu về sự khác biệt giữa hai cách tiếp cận này. Bạn cũng đã học cách tạo các thuộc tính chỉ đọc, chỉ đọc và ghi

Trong các phần sau, bạn sẽ viết mã một số ví dụ để giúp bạn hiểu rõ hơn về thực tế các trường hợp sử dụng phổ biến của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4

Xác thực giá trị đầu vào

Một trong những trường hợp sử dụng phổ biến nhất của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là xây dựng các thuộc tính được quản lý để xác thực dữ liệu đầu vào trước khi lưu trữ hoặc thậm chí chấp nhận nó dưới dạng đầu vào an toàn. Xác thực dữ liệu là một yêu cầu phổ biến trong mã lấy đầu vào từ người dùng hoặc các nguồn thông tin khác mà bạn cho là không đáng tin cậy

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 của Python cung cấp một công cụ nhanh chóng và đáng tin cậy để xử lý xác thực dữ liệu đầu vào. Ví dụ: nghĩ lại ví dụ về
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4, bạn có thể yêu cầu các giá trị của
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 là các số hợp lệ. Vì người dùng của bạn được tự do nhập bất kỳ loại dữ liệu nào, nên bạn cần đảm bảo rằng điểm của bạn chỉ chấp nhận số

Đây là một triển khai của

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 để quản lý yêu cầu này

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
0

Các phương thức setter của

>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 sử dụng các khối xác thực dữ liệu đầu vào bằng cách sử dụng kiểu Python. Nếu cuộc gọi đến
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
66 thành công, thì dữ liệu đầu vào hợp lệ và bạn nhận được
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
67 trên màn hình của mình. Nếu
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
66 tăng
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
69, thì người dùng sẽ nhận được
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
69 với một thông báo cụ thể hơn

Ghi chú. Trong ví dụ trên, bạn sử dụng cú pháp

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
71 …
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
72 để ẩn các chi tiết nội bộ liên quan đến ngữ cảnh mà bạn đang đưa ra ngoại lệ. Từ quan điểm của người dùng cuối, những chi tiết này có thể gây nhầm lẫn và làm cho lớp học của bạn trông không được trau chuốt

Kiểm tra phần trên tài liệu để biết thêm thông tin về chủ đề này

Điều quan trọng cần lưu ý là việc gán các thuộc tính

>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 trực tiếp trong
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
13 đảm bảo rằng việc xác thực cũng xảy ra trong quá trình khởi tạo đối tượng. Không làm như vậy là một lỗi phổ biến khi sử dụng
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 để xác thực dữ liệu

Đây là cách lớp học

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 của bạn hiện đang hoạt động

>>>

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
1

Nếu bạn chỉ định các giá trị

>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 mà
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
66 có thể biến thành số dấu phẩy động, thì quá trình xác thực thành công và giá trị được chấp nhận. Nếu không, bạn nhận được một
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
69

Việc triển khai

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 này phát hiện ra một điểm yếu cơ bản của
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4. Bạn có phát hiện ra nó không?

Đó là nó. Bạn có mã lặp đi lặp lại theo các mẫu cụ thể. Sự lặp lại này phá vỡ nguyên tắc DRY (Don't Repeat Yourself), vì vậy bạn sẽ muốn cấu trúc lại mã này để tránh nó. Để làm như vậy, bạn có thể trừu tượng hóa logic lặp đi lặp lại bằng cách sử dụng bộ mô tả

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
2

Bây giờ mã của bạn ngắn hơn một chút. Bạn đã quản lý để loại bỏ mã lặp lại bằng cách xác định

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
85 làm bộ mô tả quản lý xác thực dữ liệu của bạn ở một nơi duy nhất. Mã này hoạt động giống như cách triển khai trước đó của bạn. Đi trước và cung cấp cho nó một thử

Nói chung, nếu bạn thấy mình đang sao chép và dán các định nghĩa thuộc tính xung quanh mã của mình hoặc nếu bạn phát hiện thấy mã lặp lại như trong ví dụ trên, thì bạn nên cân nhắc sử dụng một bộ mô tả phù hợp

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

Cung cấp các thuộc tính được tính toán

Nếu bạn cần một thuộc tính có thể xây dựng giá trị của nó một cách linh hoạt bất cứ khi nào bạn truy cập nó, thì

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là cách tốt nhất. Những loại thuộc tính này thường được gọi là thuộc tính được tính toán. Chúng tiện dụng khi bạn cần chúng trông giống như thuộc tính háo hức, nhưng bạn muốn chúng trở nên lười biếng

Lý do chính để tạo thuộc tính háo hức là để tối ưu hóa chi phí tính toán khi bạn truy cập thuộc tính thường xuyên. Mặt khác, nếu bạn hiếm khi sử dụng một thuộc tính nhất định, thì thuộc tính lười biếng có thể trì hoãn việc tính toán của nó cho đến khi cần thiết, điều này có thể làm cho chương trình của bạn hiệu quả hơn

Dưới đây là ví dụ về cách sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 để tạo thuộc tính được tính toán
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
88 trong lớp
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
89

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
3

Trong ví dụ này, trình khởi tạo

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
89 lấy
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
91 và
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
92 làm đối số và lưu trữ chúng trong các thuộc tính thể hiện thông thường. Thuộc tính chỉ đọc
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
88 tính toán và trả về diện tích của hình chữ nhật hiện tại mỗi khi bạn truy cập nó

Một trường hợp sử dụng phổ biến khác của các thuộc tính là cung cấp một giá trị được định dạng tự động cho một thuộc tính nhất định

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
4

Trong ví dụ này,

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
94 là thuộc tính định dạng và trả về giá của một sản phẩm cụ thể. Để cung cấp định dạng giống như tiền tệ, bạn sử dụng chuỗi f với các tùy chọn định dạng phù hợp

Ghi chú. Ví dụ này sử dụng số dấu phẩy động để biểu thị tiền tệ, đây là cách làm không tốt. Thay vào đó, bạn nên sử dụng từ thư viện chuẩn

Như một ví dụ cuối cùng về các thuộc tính được tính toán, giả sử bạn có một lớp

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 sử dụng
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
5 và
>>> from circle import Circle

>>> Circle.radius.fget


>>> Circle.radius.fset


>>> Circle.radius.fdel


>>> dir(Circle.radius)
[..., '__get__', ..., '__set__', ...]
6 làm tọa độ Descartes. Bạn muốn cung cấp tọa độ cực cho điểm của mình để bạn có thể sử dụng chúng trong một số tính toán. Hệ tọa độ cực biểu thị mỗi điểm bằng cách sử dụng khoảng cách đến gốc tọa độ và góc với trục tọa độ nằm ngang

Đây là lớp tọa độ Descartes

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 cũng cung cấp tọa độ cực được tính toán

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
5

Ví dụ này cho thấy cách tính khoảng cách và góc của một đối tượng

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
4 đã cho bằng cách sử dụng tọa độ Đề các của nó. Đây là cách mã này hoạt động trong thực tế

>>>

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
6

Khi nói đến việc cung cấp các thuộc tính được tính toán hoặc lười biếng,

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 là một công cụ khá tiện dụng. Tuy nhiên, nếu bạn đang tạo một thuộc tính mà bạn sử dụng thường xuyên, thì việc tính toán thuộc tính đó mỗi lần có thể tốn kém và lãng phí. Một chiến lược tốt là lưu trữ chúng sau khi tính toán xong

Bộ nhớ đệm thuộc tính được tính toán

Đôi khi bạn có một thuộc tính tính toán nhất định mà bạn sử dụng thường xuyên. Liên tục lặp lại cùng một phép tính có thể không cần thiết và tốn kém. Để khắc phục sự cố này, bạn có thể lưu giá trị được tính vào bộ đệm ẩn và lưu nó vào một thuộc tính dành riêng không công khai để sử dụng lại sau này

Để ngăn chặn các hành vi không mong muốn, bạn cần nghĩ đến khả năng thay đổi của dữ liệu đầu vào. Nếu bạn có một thuộc tính tính toán giá trị của nó từ các giá trị đầu vào không đổi, thì kết quả sẽ không bao giờ thay đổi. Trong trường hợp đó, bạn có thể tính toán giá trị chỉ một lần

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
7

Mặc dù việc triển khai

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 này lưu trữ chính xác đường kính được tính toán, nhưng nó có nhược điểm là nếu bạn thay đổi giá trị của
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7, thì
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 sẽ không trả về giá trị chính xác

>>>

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
8

Trong các ví dụ này, bạn tạo một hình tròn có bán kính bằng

property(fget=None, fset=None, fdel=None, doc=None)
07. Thuộc tính
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 chỉ tính toán giá trị của nó khi bạn truy cập lần đầu tiên. Đó là lý do tại sao bạn thấy độ trễ trong lần thực thi đầu tiên và không có độ trễ trong lần thực thi thứ hai. Lưu ý rằng ngay cả khi bạn thay đổi giá trị của bán kính, đường kính vẫn giữ nguyên

Nếu dữ liệu đầu vào cho một thuộc tính được tính toán bị thay đổi, thì bạn cần phải tính toán lại thuộc tính đó

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
9

Phương thức setter của thuộc tính

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 đặt lại
property(fget=None, fset=None, fdel=None, doc=None)
10 thành
property(fget=None, fset=None, fdel=None, doc=None)
11 mỗi khi bạn thay đổi giá trị của bán kính. Với bản cập nhật nhỏ này,
>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 sẽ tính toán lại giá trị của nó trong lần đầu tiên bạn truy cập nó sau mỗi lần thay đổi của
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7

>>>

property(fget=None, fset=None, fdel=None, doc=None)
0

Mát lạnh.

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 hiện đang hoạt động bình thường. Nó tính toán đường kính khi bạn truy cập lần đầu tiên và mỗi khi bạn thay đổi bán kính

Một tùy chọn khác để tạo các thuộc tính được lưu trong bộ nhớ cache là sử dụng từ thư viện chuẩn. Chức năng này hoạt động như một công cụ trang trí cho phép bạn chuyển đổi một phương thức thành một thuộc tính được lưu trong bộ nhớ cache. Thuộc tính chỉ tính toán giá trị của nó một lần và lưu trữ nó như một thuộc tính bình thường trong suốt thời gian tồn tại của thể hiện

property(fget=None, fset=None, fdel=None, doc=None)
1

Ở đây,

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0 tính toán và lưu trữ giá trị của nó khi bạn truy cập lần đầu tiên. Kiểu triển khai này phù hợp với những tính toán trong đó các giá trị đầu vào không thay đổi. Đây là cách nó hoạt động

>>>

property(fget=None, fset=None, fdel=None, doc=None)
2

Khi bạn truy cập vào

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0, bạn sẽ nhận được giá trị tính toán của nó. Giá trị đó vẫn giữ nguyên từ thời điểm này trở đi. Tuy nhiên, không giống như
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4,
property(fget=None, fset=None, fdel=None, doc=None)
19 không chặn các biến đổi thuộc tính trừ khi bạn cung cấp một phương thức setter phù hợp. Đó là lý do tại sao bạn có thể cập nhật đường kính thành
property(fget=None, fset=None, fdel=None, doc=None)
20 trong vài dòng cuối cùng

Nếu bạn muốn tạo một thuộc tính được lưu trong bộ nhớ cache không cho phép sửa đổi, thì bạn có thể sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 và như trong ví dụ sau

property(fget=None, fset=None, fdel=None, doc=None)
3

Mã này xếp chồng

>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
63 lên trên
property(fget=None, fset=None, fdel=None, doc=None)
24. Sự kết hợp của cả hai bộ trang trí sẽ tạo ra một thuộc tính được lưu trong bộ nhớ cache để ngăn chặn các đột biến

>>>

property(fget=None, fset=None, fdel=None, doc=None)
4

Trong các ví dụ này, khi bạn cố gắng gán một giá trị mới cho

>>> from circle import Circle

>>> circle = Circle(42.0)

>>> circle.radius
Get radius
42.0

>>> circle.radius = 100.0
Set radius
>>> circle.radius
Get radius
100.0

>>> del circle.radius
Delete radius
>>> circle.radius
Get radius
Traceback (most recent call last):
    ...
AttributeError: 'Circle' object has no attribute '_radius'

>>> help(circle)
Help on Circle in module __main__ object:

class Circle(builtins.object)
    ...
 |  radius
 |      The radius property.
0, bạn sẽ nhận được một
>>> from point import Point

>>> point = Point(12, 5)
>>> point.get_x()
12
>>> point.get_y()
5

>>> point.set_x(42)
>>> point.get_x()
42

>>> # Non-public attributes are still accessible
>>> point._x
42
>>> point._y
5
53 vì chức năng setter đến từ bộ mô tả bên trong của
@decorator
def func(a):
    return a
4

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

Ghi nhật ký truy cập thuộc tính và đột biến

Đôi khi bạn cần theo dõi mã của mình làm gì và chương trình của bạn chạy như thế nào. Một cách để làm điều đó trong Python là sử dụng

property(fget=None, fset=None, fdel=None, doc=None)
28. Mô-đun này cung cấp tất cả các chức năng bạn cần để ghi nhật ký mã của mình. Nó sẽ cho phép bạn liên tục xem mã và tạo thông tin hữu ích về cách thức hoạt động của nó

Nếu bạn cần theo dõi cách thức và thời điểm bạn truy cập và thay đổi một thuộc tính nhất định, thì bạn cũng có thể tận dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 cho việc đó

property(fget=None, fset=None, fdel=None, doc=None)
5

Tại đây, trước tiên bạn nhập

property(fget=None, fset=None, fdel=None, doc=None)
28 và xác định cấu hình cơ bản. Sau đó, bạn triển khai
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 với thuộc tính được quản lý
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7. Phương thức getter tạo thông tin nhật ký mỗi khi bạn truy cập vào
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7 trong mã của mình. Phương thức setter ghi lại từng đột biến mà bạn thực hiện trên
# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
7. Nó cũng ghi lại những tình huống mà bạn gặp lỗi do dữ liệu đầu vào không hợp lệ

Đây là cách bạn có thể sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
6 trong mã của mình

>>>

property(fget=None, fset=None, fdel=None, doc=None)
6

Ghi nhật ký dữ liệu hữu ích từ truy cập thuộc tính và biến đổi có thể giúp bạn gỡ lỗi mã của mình. Ghi nhật ký cũng có thể giúp bạn xác định các nguồn đầu vào dữ liệu có vấn đề, phân tích hiệu suất mã của bạn, phát hiện các kiểu sử dụng, v.v.

Quản lý xóa thuộc tính

Bạn cũng có thể tạo các thuộc tính thực hiện chức năng xóa. Đây có thể là một trường hợp sử dụng hiếm hoi của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4, nhưng có một cách để xóa một thuộc tính có thể hữu ích trong một số trường hợp

Giả sử bạn đang triển khai kiểu dữ liệu cây của riêng mình. Cây là một kiểu dữ liệu trừu tượng lưu trữ các phần tử trong một hệ thống phân cấp. Các thành phần cây thường được gọi là các nút. Mỗi nút trong cây có một nút cha, ngoại trừ nút gốc. Các nút có thể có 0 hoặc nhiều nút con

Bây giờ, giả sử bạn cần cung cấp cách xóa hoặc xóa danh sách con của một nút nhất định. Đây là một ví dụ triển khai nút cây sử dụng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 để cung cấp hầu hết các chức năng của nó, bao gồm khả năng xóa danh sách nút con của nút hiện tại

property(fget=None, fset=None, fdel=None, doc=None)
7

Trong ví dụ này,

property(fget=None, fset=None, fdel=None, doc=None)
38 đại diện cho một nút trong kiểu dữ liệu cây tùy chỉnh của bạn. Mỗi nút lưu các nút con của nó trong danh sách Python. Sau đó, bạn triển khai
property(fget=None, fset=None, fdel=None, doc=None)
39 làm thuộc tính để quản lý danh sách trẻ em cơ bản. Phương thức xóa gọi _______ 46 ______ 40 trong danh sách con để xóa tất cả

>>>

property(fget=None, fset=None, fdel=None, doc=None)
8

Tại đây, trước tiên bạn tạo một nút

property(fget=None, fset=None, fdel=None, doc=None)
41 để bắt đầu điền vào cây. Sau đó, bạn tạo hai nút mới và gán chúng cho
property(fget=None, fset=None, fdel=None, doc=None)
39 bằng danh sách. Câu lệnh kích hoạt phương thức xóa nội bộ của
property(fget=None, fset=None, fdel=None, doc=None)
39 và xóa danh sách

Tạo API lớp tương thích ngược

Như bạn đã biết, thuộc tính biến lời gọi phương thức thành tra cứu thuộc tính trực tiếp. Tính năng này cho phép bạn tạo API sạch và Pythonic cho các lớp học của mình. Bạn có thể hiển thị công khai các thuộc tính của mình mà không cần các phương thức getter và setter

Nếu bạn cần sửa đổi cách bạn tính toán một thuộc tính công khai đã cho, thì bạn có thể biến nó thành một thuộc tính. Các thuộc tính giúp có thể thực hiện xử lý bổ sung, chẳng hạn như xác thực dữ liệu mà không phải sửa đổi các API công khai của bạn

Giả sử bạn đang tạo một ứng dụng kế toán và bạn cần một lớp cơ sở để quản lý tiền tệ. Để đạt được điều này, bạn tạo một lớp

property(fget=None, fset=None, fdel=None, doc=None)
45 hiển thị hai thuộc tính,
property(fget=None, fset=None, fdel=None, doc=None)
46 và
property(fget=None, fset=None, fdel=None, doc=None)
47

property(fget=None, fset=None, fdel=None, doc=None)
9

Lớp này trông sạch sẽ và Pythonic. Bây giờ giả sử rằng yêu cầu của bạn thay đổi và bạn quyết định lưu trữ tổng số xu thay vì đơn vị và xu. Xóa

property(fget=None, fset=None, fdel=None, doc=None)
46 và
property(fget=None, fset=None, fdel=None, doc=None)
47 khỏi API công khai của bạn để sử dụng thứ gì đó như
property(fget=None, fset=None, fdel=None, doc=None)
50 sẽ phá vỡ nhiều mã của một khách hàng

Trong tình huống này,

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4 có thể là một lựa chọn tuyệt vời để giữ nguyên API hiện tại của bạn. Đây là cách bạn có thể giải quyết vấn đề và tránh vi phạm mã của khách hàng

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
0

Giờ đây, lớp của bạn lưu trữ tổng số xu thay vì các đơn vị và xu độc lập. Tuy nhiên, người dùng của bạn vẫn có thể truy cập và thay đổi

property(fget=None, fset=None, fdel=None, doc=None)
46 và
property(fget=None, fset=None, fdel=None, doc=None)
47 trong mã của họ và nhận được kết quả tương tự như trước đây. Đi trước và cung cấp cho nó một thử

Khi bạn viết thứ gì đó mà nhiều người sẽ xây dựng dựa trên đó, bạn cần đảm bảo rằng các sửa đổi đối với triển khai nội bộ không ảnh hưởng đến cách người dùng cuối làm việc với các lớp của bạn

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

Thuộc tính ghi đè trong các lớp con

Khi bạn tạo các lớp Python bao gồm các thuộc tính và phát hành chúng trong một gói hoặc thư viện, bạn nên mong đợi người dùng của mình thực hiện nhiều việc khác nhau với chúng. Một trong những điều đó có thể là phân lớp chúng để tùy chỉnh các chức năng của chúng. Trong những trường hợp này, người dùng của bạn phải cẩn thận và nhận thức được một dấu hiệu cố ý tinh vi. Nếu bạn ghi đè một phần thuộc tính thì bạn sẽ mất chức năng không ghi đè

Ví dụ: giả sử bạn đang viết mã lớp

property(fget=None, fset=None, fdel=None, doc=None)
54 để quản lý thông tin nhân viên trong hệ thống kế toán nội bộ của công ty bạn. Bạn đã có một lớp tên là
property(fget=None, fset=None, fdel=None, doc=None)
55 và bạn nghĩ về việc phân lớp nó để sử dụng lại các chức năng của nó

property(fget=None, fset=None, fdel=None, doc=None)
55 có thuộc tính
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
38 được triển khai dưới dạng thuộc tính. Việc triển khai hiện tại của
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
38 không đáp ứng yêu cầu trả lại tên bằng chữ in hoa. Đây là cách bạn giải quyết vấn đề này

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
1

Trong

property(fget=None, fset=None, fdel=None, doc=None)
54, bạn ghi đè lên
>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
38 để đảm bảo rằng khi bạn truy cập thuộc tính, bạn sẽ nhận được tên nhân viên bằng chữ in hoa

>>>

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
2

Tuyệt vời.

property(fget=None, fset=None, fdel=None, doc=None)
54 hoạt động như bạn cần. Nó trả về tên bằng chữ in hoa. Tuy nhiên, các thử nghiệm tiếp theo phát hiện ra một hành vi không mong muốn

>>>

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
3

Chuyện gì đã xảy ra thế? . Trong ví dụ này, bạn chỉ triển khai lại phương thức getter. Do đó,

>>> class Point:
..     def __init__(self, x, y):
..         self.x = x
..         self.y = y
...

>>> point = Point(12, 5)
>>> point.x
12
>>> point.y
5

>>> point.x = 42
>>> point.x
42
38 đã mất phần còn lại của chức năng từ lớp cơ sở. Bạn không còn phương thức setter nữa

Ý tưởng là nếu bạn cần ghi đè một thuộc tính trong một lớp con, thì bạn nên cung cấp tất cả chức năng bạn cần trong phiên bản mới của thuộc tính đó.

Phần kết luận

Thuộc tính là một loại thành viên lớp đặc biệt cung cấp chức năng ở đâu đó giữa các thuộc tính và phương thức thông thường. Các thuộc tính cho phép bạn sửa đổi việc triển khai các thuộc tính cá thể mà không thay đổi API công khai của lớp. Khả năng giữ nguyên các API của bạn giúp bạn tránh vi phạm mã mà người dùng của bạn đã viết trên các phiên bản cũ hơn của lớp học của bạn

Các thuộc tính là cách Pythonic để tạo các thuộc tính được quản lý trong các lớp của bạn. Chúng có một số trường hợp sử dụng trong lập trình trong thế giới thực, khiến chúng trở thành sự bổ sung tuyệt vời cho bộ kỹ năng của bạn với tư cách là nhà phát triển Python

Trong hướng dẫn này, bạn đã học cách

  • Tạo các thuộc tính được quản lý với
    # circle.py
    
    class Circle:
        def __init__(self, radius):
            self._radius = radius
    
        def _get_radius(self):
            print("Get radius")
            return self._radius
    
        def _set_radius(self, value):
            print("Set radius")
            self._radius = value
    
        def _del_radius(self):
            print("Delete radius")
            del self._radius
    
        radius = property(
            fget=_get_radius,
            fset=_set_radius,
            fdel=_del_radius,
            doc="The radius property."
        )
    
    4 của Python
  • Thực hiện đánh giá thuộc tính lười biếng và cung cấp các thuộc tính được tính toán
  • Tránh các phương thức setter và getter có thuộc tính
  • Tạo các thuộc tính chỉ đọc, chỉ đọc và ghi
  • Tạo các API nhất quán và tương thích ngược cho các lớp của bạn

Bạn cũng đã viết một số ví dụ thực tế hướng dẫn bạn về các trường hợp sử dụng phổ biến nhất của

# circle.py

class Circle:
    def __init__(self, radius):
        self._radius = radius

    def _get_radius(self):
        print("Get radius")
        return self._radius

    def _set_radius(self, value):
        print("Set radius")
        self._radius = value

    def _del_radius(self):
        print("Delete radius")
        del self._radius

    radius = property(
        fget=_get_radius,
        fset=_set_radius,
        fdel=_del_radius,
        doc="The radius property."
    )
4. Những ví dụ đó bao gồm đầu vào, thuộc tính được tính toán, ghi nhật ký mã của bạn, v.v.

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

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Quản lý thuộc tính với thuộc tính của Python()

🐍 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

Thuộc tính set được sử dụng để làm gì trong python?

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

Giới thiệu về Leodanis Pozo Ramos

Thuộc tính set được sử dụng để làm gì trong python?
Thuộc tính set được sử dụng để làm gì trong python?

Leodanis là một kỹ sư công nghiệp yêu thích Python và phát triển phần mềm. Anh ấy là một nhà phát triển Python tự học với hơn 6 năm kinh nghiệm. Anh ấy là một nhà văn đam mê kỹ thuật với số lượng bài báo được xuất bản ngày càng tăng trên Real Python và các trang web khác

» Tìm hiểu thêm về Leodanis


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à

Thuộc tính set được sử dụng để làm gì trong python?

Aldren

Thuộc tính set được sử dụng để làm gì trong python?

Bartosz

Thuộc tính set được sử dụng để làm gì trong python?

Martin

Thuộc tính set được sử dụng để làm gì trong python?

Sadie

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

Khi nào nên sử dụng Setattr trong Python?

Hàm setattr() của Python được sử dụng để đặt giá trị cho thuộc tính của đối tượng . Nó nhận ba đối số là một đối tượng, một chuỗi và một giá trị tùy ý và không trả về giá trị nào. Nó hữu ích khi chúng ta muốn thêm một thuộc tính mới vào một đối tượng và đặt giá trị cho nó.

__ Setattr __ trong Python là gì?

Phương thức setattr() của Python được dùng để gán giá trị cho thuộc tính đối tượng .

Getattr và Setattr trong Python là gì?

Python setattr() và getattr() song hành cùng nhau. Như chúng ta đã thấy getattr() làm gì; . cú pháp. Sử dụng Trình duyệt khác. setattr(đối tượng, tên, giá trị)The setattr() function is used to assign a new value to an object/instance attribute. Syntax. Use a different Browser. setattr(object, name, value)