Underscore(_) trong Python
Bài đăng này đã không được cập nhật trong 5 năm
Khi lập trình với Python, bạn thi thoảng sẽ gặp case sử dụng Single Underscore (_) và Double Underscores (__).
Vậy điều mà newbie sẽ gặp phải là sử dụng underscore như thế nào?
Bài viết này chia sẽ về cách sử dụng underscore sao cho hợp lý dựa vào:
- Python syntax
- Code convention
Using in interpreters
Trong Cpython và một vài Python interpreters khác, last expression value sẽ được store vào một special variable được gọi là '_'.
Exp:
$ 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
Ignoring the values
Giả sử ta nhận được một value là một tuple. Exmp:
>>> tuple_exm = (10, range(1, 10), "Hello")
Để lấy được range(1, 10)
sẽ có 2 cách:
C1: Đơn giản là lấy dựa vào index.
>>> print(tuple_exm[1])
range(1, 10)
Hoặc: Nếu value nhận được mình chỉ muốn xử lý là range(1, 10)
thì ta sẽ có cách khác:
>>> _, range_exm, _ = tuple_exm
>>> print(tuple_exm[1])
range(1, 10)
Một ví dụ khác:
for _ in range(1, 10):
do_something()
Chốt lại, underscore
được sử dụng để ignoring specific values nếu specific values đó không được sử dụng.
Declaring variable and function
Code convention
Naming Styles trong PEP8 sử dụng rất nhiều underscore
. Cụ thể là:
- Variable
- Method
- Constant
- Module
Trích dẫn từ PEP8: https://www.python.org/dev/peps/pep-0008/
The following naming styles are commonly distinguished:
...
- lower_case_with_underscores
...
- UPPER_CASE_WITH_UNDERSCORES
Tất nhiêu nếu bạn không tuân thủ code theo PEP8 thì cũng chả sao . Code bạn vẫn sẽ chạy bình thường.
Non-public
Nếu như các bạn đã học Java hay C++ chắc hẳn sẽ biết về access medifiers: private
, public
hay protected
. Nhưng
Python không có điều đó.
Thay vào đó, những methods và instance variables non-public sẽ cần sử dụng one leading underscore
.
Giả sử ta có 1 class parent:
>>> class Parent(object):
... def public(self):
... pass
... def _protected(self):
... pass
... def __private(self):
... pass
...
Tiếp tục tạo 1 class child extend class parent bên trên và tạo một method method_one:
>>> class Child(Parent):
def method_one(self):
pass
Với method public
và _protected
ở class parent ta dễ dàng gọi nó trong method_one
bằng cách:
>>> def method_one(self):
self.public()
self._protected()
>>> x = Child()
>>> x.method_one() # Không có lỗi
Nhưng sẽ lỗi nếu làm 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âu thần chú mà bạn cần lúc này:
_ClassName__method_name
App dụng vào ví dụ của trên của mình:
>>> def method_one(self):
self._Parent__private()
>>> x = Child()
>>> x.method_one()
Vi diệu chưa
Avoiding conflict with Python keywords or built-ins.
Cái này có thể hiểu đơn giản là giả sử bạn muốn sử dụng từ list
. Nhưng từ này phạm húy nên bạn sẽ cần chỉnh là một xíu là list_
là ok
Declaring special methods
Bạn sẽ thường xuyên gặp các method kiểu như:
>>> def __init__(self):
do_something()
hay
>>> def __next__(self):
do_something()
Thường những method này sẽ có những features đặc biệt.
i18n/l10n function
Đây thuộc về convention. Ở đây, underscore bind i18n/l10n to underscore variable.
Thông tin nhiều hơn các bạn có thể tham khảo ở đây:
https://docs.python.org/3/library/gettext.html
Separate digits
Đây là tính năng được added vào từ bản Python 3.6.
>>> dec_base = 1_000_000
>>> print(dec_base)
1000000
Conclusion
Nếu bạn đã đọc hết tới đây, bạn sẽ thấy có vài điểm mấu chốt. Khi sử dụng underscore
thì có những thứ thuộc về syntax phải bắt buộc phải làm theo. Có những thứ thuộc về convention thì tùy bạn =)).
Source: https://hackernoon.com/understanding-the-underscore-of-python-309d1a029edc
All rights reserved