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.
classSampleClass:def__init__(self, a):## private varibale or property in Python
self.__a = a
## getter method to get the properties using an objectdefget_a(self):return self.__a
## setter method to change the value 'a' using an objectdefset_a(self, a):
self.__a = a
Được hỗ trợ bởi
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() methodprint(obj.get_a())## setting a new value to the 'a' using set_a() method
obj.set_a(45)print(obj.get_a())Được hỗ trợ bởi
Đâ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.
classPythonicWay:def__init__(self, a):
self.a = a
Được hỗ trợ bởi
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)Được hỗ trợ bởi
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.
classSampleClass1: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 objectdefget_a(self):return self.__a
## setter method to change the value 'a' using an objectdefset_a(self, a):## condition to check whether 'a' is suitable or notif a >0and a %2==0:
self.__a = a
else:
self.__a =2Được hỗ trợ bởi
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())Được hỗ trợ bởi
Hãy xem cách triển khai lớp trên bằng decorator @property.
classProperty:def__init__(self, var):## initializing the attribute
self.a = var
@propertydefa(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.setterdefa(self, var):if var >0and var %2==0:
self.__a = var
else:
self.__a =2Được hỗ trợ bởi
@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)Được hỗ trợ bởi
@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à...
classAnotherWay: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 objectdefget_a(self):return self.__a
## setter method to change the value 'a' using an objectdefset_a(self, var):## condition to check whether var is suitable or notif var >0and var %2==0:
self.__a = var
else:
self.__a =2
a =property(get_a, set_a)Được hỗ trợ bởi
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)Được hỗ trợ bởi
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é.
classFinalClass: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 objectdef__get_a(self):return self.__a
## setter method to change the value 'a' using an objectdef__set_a(self, var):## condition to check whether var is suitable or notif var >0and var %2==0:
self.__a = var
else:
self.__a =2
a =property(__get_a, __set_a)Được hỗ trợ bởi
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)Được hỗ trợ bởi
Getters và Setters là gì?
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.
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.
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.
Đâ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.
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ử.
Sự khác nhau giữa hai lớp trên là gì?
Nên dùng cái nào?
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.
Hãy kiểm tra lớp bằng cách tạo một đối tượng.
Hãy xem cách triển khai lớp trên bằng decorator @property.
@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.
@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à...
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.
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é.
Hãy kiểm tra xem nó có hoạt động đúng không.
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ẻ!