Property là một loại thành viên đặc biệt trong class Python cho phép truy xất và kiểm soát truy xuất một [instance] attribute cụ thể. Property rất quan trọng và được khuyến khích sử dụng khi xây dựng các class chuyên để chứa dữ liệu [như domain class trong các ứng dụng quản lý]. Python cung cấp một số cách khác nhau để khai báo property.
Mô hình getter/setter trong Python class
Trong class Python, mặc định mọi biến thành viên [instance attribute] đều là public. Do đó, mọi biến thành viên trong Python đều được truy xuất tự do.
Điều này làm xuất hiện một vấn đề: kiểm soát dữ liệu. Ví dụ, tuổi của con người không thể là một số âm. Tương như vậy, tên của con người không thể là những cụm ký tự bất kỳ được.
Để thực hiện việc kiểm soát xuất nhập dữ liệu cho object, các ngôn ngữ lập trình hướng đối tượng thường sử dụng mô hình getter/setter. Hãy thực hiện mô hình này trên class Person:
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' putin = Person[] putin.set_fname['Putin'] putin.set_lname['Vladimir'] putin.set_age[66] print[putin.get_name[]]
Theo mô hình này, biến cần kiểm soát dữ liệu sẽ đặt mức truy cập là private. Tức là code ngoài class không nên thay đổi giá trị của biến. Trong Python bạn sử dụng name mangling __age
, __fname
, __lname
[hai dấu gạch chân] cho biến private khi khai báo biến thành viên đó trong hàm tạo
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]0.
Ứng với mỗi biến private bạn xây dựng hai phương thức get/set để xuất/nhập dữ liệu. Ví dụ, với biến thành viên __age
, bạn xây dựng phương thức
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]2 để nhập dữ liệu cho
__age
, và class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]4 để trả lại dữ liệu chứa trong
__age
. Cặp phương thức get/set như vậy được gọi chung là getter và setter. Tương tự, chúng ta xây dựng class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]6/
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]7 cho
__fname
, class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]9 cho
__lname
.Trong getter và setter, tùy vào yêu cầu kiểm soát bạn có thể thực hiện logic riêng. Ví dụ, trong set_age[], bạn chỉ gán giá trị mới cho __age nếu giá trị đó lớn hơn 0; trong
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]7 và
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]2 – điều kiện gán là chuỗi chỉ chứa ký tự chữ cái [kiểm tra
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]3 trả lại kết quả True].
Property trong Python, hàm property[]
Mô hình getter/setter như trên hoạt động tốt. Nhiều ngôn ngữ khuyến khích vận dụng và phát triển mô hình đó. Ví dụ, trong C# cung cấp một số cú pháp tắt để nhanh chóng tạo ra các cặp getter/setter và gọi loại cú pháp đó là C# property.
Trong Python bạn có thể tiếp tục sử dụng mô hình getter/setter như trên. Tuy nhiên, khi sử dụng mô hình này, trong code của bạn chứa quá nhiều lời gọi hàm khiến code nhìn thiếu tự nhiên và khó đọc.
Python đưa ra giải pháp riêng. Hãy điều chỉnh code như sau:
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
Hãy để ý nhóm lệnh đặc biệt trong class Person:
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]
Khi tồn tại nhóm lệnh này, bạn có thể viết code sử dụng class như sau:
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
Khi này,
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]4,
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]5 và
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]6 trở thành các property trong class Python.property trong class Python.
Trong class Python, property là một dạng giao diện tới các instance attribute để thực hiện xuất/nhập dữ liệu qua bộ getter/setter. Mỗi property cung cấp một cách thức tự nhiên để nhập xuất dữ liệu cho một instance attribute qua phép gán và phép toán truy xuất phần tử thông thường. Property hoàn toàn che đi lời gọi hàm getter/setter thực tế.
Như vậy, khi sử dụng property
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]4, bạn có thể dùng cách viết tự nhiên
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]8 giống như một biến thành viên thông thường để truy xuất dữ liệu từ biến private
__fname
. Phép gán giá trị cho first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]4 sẽ chuyển thành lời gọi hàm
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]7, lệnh đọc giá trị
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]4 sẽ chuyển thành lời gọi hàm
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age def set_age[self, age: int]: if age > 0: self.__age = age def get_age[self]: return self.__age def get_lname[self]: return self.__lname def set_lname[self, lname: str]: if lname.isalpha[]: self.__lname = lname def get_fname[self]: return self.__fname def set_fname[self, fname: str]: if fname.isalpha[]: self.__fname = fname def get_name[self]: return f'{self.__fname} {self.__lname}' first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age] def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]6.
Python cung cấp hai cách để tạo property: sử dụng hàm
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]4 và sử dụng
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]5 decorator.
Ở trên chúng ta vừa sử dụng hàm
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]4.
Hàm property[] nhận 3 tham số tương ứng với tên hàm getter, setter và deleter. Kết quả của lời gọi hàm property chính là một biến mà bạn có thể sử dụng làm property tương ứng của attribute.getter, setter và deleter. Kết quả của lời gọi hàm property chính là một biến mà bạn có thể sử dụng làm property tương ứng của attribute.
Getter và setter thì bạn đã biết. Còn deleter là hàm được gọi tương ứng với lệnh
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]7 của Python. Ví dụ, khi gọi lệnh
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]8 thì sẽ gọi tới deleter tương ứng. Trên thực tế deleter ít được sử dụng hơn.
Nếu thiếu setter, property trở thành chỉ đọc [read-only].
Tạo property với decorator
Một phương pháp đơn giản hơn để tạo property là sử dụng @property decorator.
Hãy thay đổi code của Person như sau:
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age @property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age @property def first_name[self]: return self.__fname @first_name.setter def first_name[self, fname: str]: if fname.isalpha[]: self.__fname = fname @property def last_name[self]: return self.__lname @last_name.setter def last_name[self, lname: str]: if lname.isalpha[]: self.__lname = lname @property def full_name[self]: return f'{self.__fname} {self.__lname}' def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
Bạn có thể thấy code của Person giờ tương đối khác biệt và ngắn gọn hơn. Hãy để ý các dòng được đánh dấu. Đây là khối code dùng để tạo ra property sử dung @property decorator.
Lấy ví dụ:
@property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age
Bạn để ý mấy vấn đề sau:
- Cả getter và setter [và cả deleter] giờ sử dụng chung một tên, và đó cũng là tên của property. Ví dụ nếu bạn cần tạo
first_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]
6 property để truy xuất giá trị cho attribute__age
thì cần tạo getter, setter và deleter với cùng một tênfirst_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]
6. - Phương thức getter cần đánh dấu với
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
5 decorator. - Phương thức setter cần đánh dấu với cấu trúc
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age @property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age @property def first_name[self]: return self.__fname @first_name.setter def first_name[self, fname: str]: if fname.isalpha[]: self.__fname = fname @property def last_name[self]: return self.__lname @last_name.setter def last_name[self, lname: str]: if lname.isalpha[]: self.__lname = lname @property def full_name[self]: return f'{self.__fname} {self.__lname}' def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
3, phương thức deleter cần đánh dấu với cấu trúcclass Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age @property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age @property def first_name[self]: return self.__fname @first_name.setter def first_name[self, fname: str]: if fname.isalpha[]: self.__fname = fname @property def last_name[self]: return self.__lname @last_name.setter def last_name[self, lname: str]: if lname.isalpha[]: self.__lname = lname @property def full_name[self]: return f'{self.__fname} {self.__lname}' def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
4. Ví dụ, vớifirst_name = property[get_fname, set_fname] last_name = property[get_lname, set_lname] full_name = property[get_name] age = property[get_age, set_age]
6 property thì setter phải dánh dấuclass Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age @property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age @property def first_name[self]: return self.__fname @first_name.setter def first_name[self, fname: str]: if fname.isalpha[]: self.__fname = fname @property def last_name[self]: return self.__lname @last_name.setter def last_name[self, lname: str]: if lname.isalpha[]: self.__lname = lname @property def full_name[self]: return f'{self.__fname} {self.__lname}' def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
6, deleter phải đánh dấuclass Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age @property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age @property def first_name[self]: return self.__fname @first_name.setter def first_name[self, fname: str]: if fname.isalpha[]: self.__fname = fname @property def last_name[self]: return self.__lname @last_name.setter def last_name[self, lname: str]: if lname.isalpha[]: self.__lname = lname @property def full_name[self]: return f'{self.__fname} {self.__lname}' def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
7. - Nếu chỉ có getter, property trở thành read-only. Ví dụ,
class Person: def __init__[self, fname: str = '', lname: str = '', age: int = 18]: self.__fname = fname self.__lname = lname self.__age = age @property def age[self]: return self.__age @age.setter def age[self, age: int]: if age > 0: self.__age = age @property def first_name[self]: return self.__fname @first_name.setter def first_name[self, fname: str]: if fname.isalpha[]: self.__fname = fname @property def last_name[self]: return self.__lname @last_name.setter def last_name[self, lname: str]: if lname.isalpha[]: self.__lname = lname @property def full_name[self]: return f'{self.__fname} {self.__lname}' def print[self, format = True]: if not format: print[self.name, self.age] else: print[f'{self.full_name}, {self.age} years old'] putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
8 là một property chỉ đọc.
@property def full_name[self]: return f'{self.__fname} {self.__lname}'
Rõ ràng, cấu trúc khai báo property này đơn giản ngắn gọn và dễ đọc hơn.
Kết luận
Trong bài học này chúng ta đã làm quen với property trong Python với các ý chính sau:
- Property là loại thành phần tương đối đặc biệt cho phép kết hợp giữa attribute và method để kiểm soát truy xuất dữ liệu cho attribute.
- Python cung cấp hai cú pháp để xây dựng property: sử dụng hàm
putin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
4 và sử dụngputin = Person[] putin.first_name = 'Putin' putin.last_name = 'Vladimir' putin.age = 66 print[putin.full_name, putin.age]
5 decorator. Trong đó cú pháp decorator đơn giản gọn nhẹ và dễ đọc hơn. - Dù sử dụng phương pháp nào, cần lưu ý rằng property thực chất chỉ là giao diện để gọi tới các phương thức getter, setter và deleter cho attribute theo cách thức tiện lợi hơn.
+ Nếu bạn thấy site hữu ích, trước khi rời đi hãy giúp đỡ site bằng một hành động nhỏ để site có thể phát triển và phục vụ bạn tốt hơn.+ Nếu bạn thấy bài viết hữu ích, hãy giúp chia sẻ tới mọi người.+ Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần thảo luận cuối trang.Cảm ơn bạn!giúp đỡ site bằng một hành động nhỏ để site có thể phát triển và phục vụ bạn tốt hơn.
+ Nếu bạn thấy bài viết
hữu ích, hãy giúp chia sẻ tới mọi người.
+ Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần thảo luận cuối trang.
Cảm ơn bạn!