Khi lập trình bằng Python, bạn thỉnh thoảng sẽ gặp trường hợp sử dụng dấu gạch dưới đơn (_) và dấu gạch dưới kép (__). Vậy làm sao sử dụng dấu gạch dưới một cách hợp lý?
Bài viết này sẽ chia sẻ về cách sử dụng dấu gạch dưới sao cho phù hợp, dựa trên:
- Cú pháp Python
- Quy ước viết code
Sử dụng trong các trình thông dịch
Trong CPython và một số trình thông dịch Python khác, giá trị của biểu thức cuối cùng sẽ được lưu vào một biến đặc biệt có tên là “_”.
Ví dụ:
$ python
Python 3.6.5 (default, Jan 9 2019, 14:12:28)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1
1
>>> _ + 2
3
>>> _ + 3
6
Bỏ qua giá trị không sử dụng
Giả sử bạn nhận được một giá trị là một tuple. Ví dụ:
>>> tuple_exm = (10, range(1, 10), "Xin chào")
Để lấy được range(1, 10)
, bạn có 2 cách:
- Cách 1: Lấy dựa vào vị trí của phần tử trong tuple.
>>> print(tuple_exm[1])
range(1, 10)
- Cách 2: Nếu bạn chỉ quan tâm đến
range(1, 10)
và không muốn sử dụng các giá trị khác, bạn có cách khác:
>>> _, range_exm, _ = tuple_exm
>>> print(range_exm)
range(1, 10)
Ví dụ khác:
for _ in range(1, 10):
lam_dieu_gi_do()
Tóm lại, dấu gạch dưới được sử dụng để bỏ qua các giá trị cụ thể nếu những giá trị đó không được sử dụng.
Khai báo biến và hàm
Quy ước viết code
Trong PEP8, có nhiều quy ước viết code sử dụng dấu gạch dưới. Cụ thể là:
- Biến
- Phương thức
- Hằng số
- Module
Trích dẫn từ PEP8: https://www.python.org/dev/peps/pep-0008/
Các kiểu viết code sau đây thường được phân biệt:
…
- lower_case_with_underscores
…
- UPPER_CASE_WITH_UNDERSCORES
Dù bạn không tuân thủ quy ước viết code của PEP8, code của bạn vẫn hoạt động bình thường.
Non-public
Nếu bạn đã học Java hoặc C++, chắc hẳn bạn biết về các từ khóa truy cập như private
, public
hoặc protected
. Nhưng Python không có những từ khóa đó.
Thay vào đó, các phương thức và biến non-public cần sử dụng một dấu gạch dưới ở đầu.
Giả sử bạn có một lớp cha:
>>> class Parent(object):
... def public(self):
... pass
... def _protected(self):
... pass
... def __private(self):
... pass
Tiếp theo, tạo một lớp con kế thừa từ lớp cha và tạo một phương thức method_one
:
>>> class Child(Parent):
... def method_one(self):
... pass
Với các phương thức public
và _protected
trong lớp cha, bạn có thể gọi chúng trong method_one
như sau:
>>> def method_one(self):
... self.public()
... self._protected()
>>> x = Child()
>>> x.method_one()
# Không có lỗi
Tuy nhiên, sẽ có lỗi nếu bạn thực hiện tương tự với method __private
.
>>> def method_one(self):
... self.__private()
>>> x = Child()
>>> x.method_one()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in method_one
AttributeError: 'Child' object has no attribute '_Child__private'
Đây là cú pháp ma thuật mà bạn cần dùng ở thời điểm này:
_TênLớp__tên_phương_thức
Áp dụng vào ví dụ trên:
>>> def method_one(self):
... self._Parent__private()
>>> x = Child()
>>> x.method_one()
Amazing, phải không?
Tránh xung đột với các từ khóa hoặc tên sẵn có trong Python
Cái này dễ hiểu: giả sử bạn muốn sử dụng từ list
. Nhưng từ này bị trùng nên bạn chỉ cần thay một chút thành list_
là được.
Khai báo các phương thức đặc biệt
Bạn sẽ thường xuyên gặp các phương thức như:
>>> def __init__(self):
... lam_dieu_gi_do()
hoặc
>>> def __next__(self):
... lam_dieu_gi_do()
Những phương thức như thế thường có những tính năng đặc biệt.
Hàm i18n/l10n
Đây là quy ước. Ở đây, dấu gạch dưới kết hợp i18n/l10n với biến dấu gạch dưới.
Thông tin chi tiết bạn có thể tham khảo tại đây:
https://docs.python.org/3/library/gettext.html
Tách các chữ số
Đây là một tính năng được thêm vào từ phiên bản Python 3.6.
>>> dec_base = 1_000_000
>>> print(dec_base)
1000000
Kết luận
Nếu bạn đã đọc đến cuối bài viết này, bạn sẽ nhận thấy có một số điểm chính. Khi sử dụng dấu gạch dưới, có những thứ thuộc về cú pháp bạn phải tuân thủ. Có những thứ thuộc về quy ước thì tùy bạn =)).
Nguồn: Link đích
Để biết thêm thông tin, hãy truy cập trang web LADEC.