Chuyển đến nội dung chính

Property so với Getters và Setters trong Python

Trong hướng dẫn này, bạn sẽ học sự khác biệt giữa Property trong Python và Getters & Setters.
· 6 phút đọc

Khám phá cùng AI

Getters và Setters là gì?

  • Getters: Đây là các phương thức trong lập trình hướng đối tượng (OOP) giúp truy cập các thuộc tính riêng tư của một lớp.
  • Setters: Đây là các phương thức trong OOP giúp gán giá trị cho các thuộc tính riêng tư trong một lớp.

Thuộc tính riêng tư - Bao đóng (Encapsulation)

Nếu bạn chưa quen với thuộc tính riêng tư hoặc phương thức riêng tư trong Python, hãy đọc bài viết này của DataCamp.

Hãy xem cách bạn có thể triển khai một thuộc tính riêng tư trong Python.

class SampleClass:

    def __init__(self, a):
        ## private varibale or property in Python
        self.__a = a

    ## getter method to get the properties using an object
    def get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def set_a(self, a):
        self.__a = a

SampleClass có ba phương thức.

  • __init__:- Dùng để khởi tạo các thuộc tính của một lớp.

    • __a:- Đây là một thuộc tính riêng tư.
  • get_a:- Dùng để lấy giá trị của thuộc tính riêng tư a.
  • set_a:- Dùng để gán giá trị cho a thông qua một đối tượng của lớp.

Bạn không thể truy cập trực tiếp các biến riêng tư trong Python. Đó là lý do bạn triển khai phương thức getter.

Hãy xem lớp hoạt động như thế nào.

## creating an object
obj = SampleClass(10)

## getting the value of 'a' using get_a() method
print(obj.get_a())

## setting a new value to the 'a' using set_a() method
obj.set_a(45)

print(obj.get_a())
10
45

Đây là cách bạn triển khai thuộc tính riêng tư, getters và setters trong Python. Quy trình tương tự cũng được dùng trong Java. Hãy viết lại cùng cách triển khai theo phong cách Pythonic.

class PythonicWay:

    def __init__(self, a):
        self.a = a

Bạn không cần các phương thức getter, setter để truy cập hoặc thay đổi thuộc tính. Bạn có thể truy cập trực tiếp bằng tên thuộc tính.

Hãy xem thử.

## Creating an object for the 'PythonicWay' class
obj = PythonicWay(100)

print(obj.a)
100

Sự khác nhau giữa hai lớp trên là gì?

  • SampleClass ẩn các thuộc tính và phương thức riêng tư. Nó triển khai tính năng bao đóng của OOP.
  • PythonicWay không ẩn dữ liệu. Nó không triển khai tính năng bao đóng.

Nên dùng cái nào?

  • Tùy vào nhu cầu. Nếu bạn muốn có thuộc tính và phương thức riêng tư, bạn có thể triển khai lớp bằng các phương thức setter, getter; nếu không, bạn có thể triển khai theo cách thông thường.

Property

Vậy nếu bạn muốn áp dụng một số điều kiện khi gán giá trị cho một thuộc tính trong SampleClass thì sao?

Giả sử nếu giá trị truyền vào là số chẵn và dương thì gán cho thuộc tính, ngược lại gán giá trị là 2.

Hãy triển khai điều này bằng cách thay đổi phương thức set_a() trong SampleClass.

class SampleClass1:

    def __init__(self, a):
        ## calling the set_a() method to set the value 'a' by checking certain conditions
        self.set_a(a)

    ## getter method to get the properties using an object
    def get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def set_a(self, a):

        ## condition to check whether 'a' is suitable or not
        if a > 0 and a % 2 == 0:
            self.__a = a
        else:
            self.__a = 2

Hãy kiểm tra lớp bằng cách tạo một đối tượng.

## creating an object for the class 'SampleClass1'
obj = SampleClass1(16)

print(obj.get_a())
16

Hãy xem cách triển khai lớp trên bằng decorator @property.

class Property:

    def __init__(self, var):
        ## initializing the attribute
        self.a = var

    @property
    def a(self):
        return self.__a

    ## the attribute name and the method name must be same which is used to set the value for the attribute
    @a.setter
    def a(self, var):
        if var > 0 and var % 2 == 0:
            self.__a = var
        else:
            self.__a = 2

@property được dùng để lấy giá trị của thuộc tính riêng tư mà không cần phương thức getter. Ta đặt dòng @property trước phương thức trả về biến riêng tư.

Để gán giá trị cho biến riêng tư, ta dùng @method_name.setter trước phương thức. Ta sử dụng nó như một setter.

Hãy kiểm thử lớp Property để xem các decorator có hoạt động đúng hay không.

## creating an object for the class 'Property'
obj = Property(23)

print(obj.a)
2

@a.setter sẽ gán giá trị cho a sau khi kiểm tra các điều kiện đã nêu trong phương thức. Một cách khác để dùng property là...

class AnotherWay:

    def __init__(self, var):
        ## calling the set_a() method to set the value 'a' by checking certain conditions
        self.set_a(var)

    ## getter method to get the properties using an object
    def get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def set_a
    (self, var):

        ## condition to check whether var is suitable or not
        if var > 0 and var % 2 == 0:
            self.__a = var
        else:
            self.__a = 2

    a = property(get_a, set_a)

Truyền tất cả phương thức getter và setter vào property và gán nó cho biến bạn muốn dùng làm thuộc tính của lớp.

## creating an object for the 'AnotherWay' class
obj = AnotherWay(28)

print(obj.a)
28

Hãy đặt các phương thức setter và getter thành riêng tư để ẩn chúng. Cùng làm nhé.

class FinalClass:

    def __init__(self, var):
        ## calling the set_a() method to set the value 'a' by checking certain conditions
        self.__set_a(var)

    ## getter method to get the properties using an object
    def __get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def __set_a(self, var):

        ## condition to check whether var is suitable or not
        if var > 0 and var % 2 == 0:
            self.__a = var
        else:
            self.__a = 2

    a = property(__get_a, __set_a)

Hãy kiểm tra xem nó có hoạt động đúng không.

## creating an object for the 'AnotherWay' class
obj = FinalClass(12)

print(obj.a)
12

Kết luận

Bạn đã thấy cách triển khai bao đóng trong Python và sự khác biệt giữa setter, getter và property.

Nếu bạn mới học Python, tôi khuyến nghị bạn học khóa miễn phí Giới thiệu về Python của DataCamp.

Nếu bạn có bất kỳ câu hỏi nào về bài viết, vui lòng để lại trong phần bình luận. Chúc bạn code vui vẻ!

Chủ đề

Liên quan