Trong Python, không tồn tại các biến instance Private mà không thể truy cập được trừ khi ta truy cập từ bên trong của một đối tượng. Tuy nhiên, một quy ước đang được tuân theo bởi hầu hết các code và các bộ code hóa trong Python, đó là một tên được thêm tiền tố gạch dưới, ví dụ _geek sẽ được coi là một phần non-public của API hoặc bất kỳ code nào trong Python, cho dù đó là một hàm, một phương thức hoặc một thành viên dữ liệu. Trong khi thực hiện điều này, chúng ta cũng sẽ cố gắng hiểu thêm khái niệm về các dạng dấu gạch dưới khác nhau, ví dụ như for _ in range(10), __init __ (self).

1. Mangling và cách thức hoạt động

Trong Python, có một thứ được gọi là name mangling, có nghĩa là có một hỗ trợ hạn chế cho trường hợp sử dụng hợp lệ cho các thành viên lớp riêng về cơ bản để tránh xung đột tên của các tên với tên được định nghĩa bởi các subclass. Bất kỳ định danh nào của mẫu __geek (ít nhất hai dấu gạch dưới hàng đầu hoặc nhiều nhất một dấu gạch dưới hàng sau) được thay thế bằng _ classname__geek, trong đó classname là tên của class hiện tại có dấu gạch dưới hàng đầu. Miễn là nó xảy ra trong định nghĩa của class, mangling này sẽ được thực hiện. Điều này rất hữu ích để cho các subclass ghi đè các phương thức mà không kết thúc gọi phương thức nội bộ.

# -----------------------------------------------------------
#Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
#@author cafedevn
#Contact: cafedevn@gmail.com
#Fanpage: https://www.facebook.com/cafedevn
#Group: https://www.facebook.com/groups/cafedev.vn/
#Instagram: https://instagram.com/cafedevn
#Twitter: https://twitter.com/CafedeVn
#Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
#Pinterest: https://www.pinterest.com/cafedevvn/
#YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
# -----------------------------------------------------------


# Python code to illustrate how mangling works 
class Map: 
    def __init__(self, iterate): 
        self.list = [] 
        self.__cafedev(iterate) 
    def cafedev(self, iterate): 
        for item in iterate: 
            self.list.append(item) 
  
    # private copy of original cafedev() method 
    __cafedev = cafedev    
  
class MapSubclass(Map): 
      
    # provides new signature for cafedev() but 
    # does not break __init__() 
    def cafedev(self, key, value):         
        for i in zip(keys, values): 
            self.list.append(i) 

Các quy tắc mangling được thiết kế chủ yếu để tránh tai nạn nhưng vẫn có thể truy cập hoặc sửa đổi một biến private. Điều này có thể hữu ích trong các trường hợp đặc biệt, chẳng hạn như trong trình gỡ lỗi.

2. _dấu gạch dưới đơn hàng đầu

Về cơ bản, một gạch chân trong phần đầu của một phương thức, hàm hoặc thành viên dữ liệu có nghĩa là bạn không nên truy cập phương thức này vì nó không phải là một phần của API. Hãy xem đoạn code này:

# -----------------------------------------------------------
#Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
#@author cafedevn
#Contact: cafedevn@gmail.com
#Fanpage: https://www.facebook.com/cafedevn
#Group: https://www.facebook.com/groups/cafedev.vn/
#Instagram: https://instagram.com/cafedevn
#Twitter: https://twitter.com/CafedeVn
#Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
#Pinterest: https://www.pinterest.com/cafedevvn/
#YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
# -----------------------------------------------------------


# Python code to illustrate  
# how single underscore works 
def _get_errors(self): 
    if self._errors is None: 
        self.full_clean() 
    return self._errors 
  
errors = property(_get_errors) 

Đoạn code được lấy từ code nguồn Django (django / Forms / Forms.py). Điều này cho thấy rằng lỗi là một thuộc tính và nó cũng là một phần của API, nhưng phương thức_get_errors là private, vì vậy người ta không nên truy cập nó.

3. __dấu gạch dưới kép hàng đầu

Hai dấu gạch chân ở đầu có thể gây ra nhiều nhầm lẫn. Đây là vấn đề về cú pháp chứ không phải là một quy ước. Dấu gạch dưới kép sẽ xáo trộn tên thuộc tính của một class để tránh xung đột tên thuộc tính giữa các class. Lấy ví dụ:

# -----------------------------------------------------------
#Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
#@author cafedevn
#Contact: cafedevn@gmail.com
#Fanpage: https://www.facebook.com/cafedevn
#Group: https://www.facebook.com/groups/cafedev.vn/
#Instagram: https://instagram.com/cafedevn
#Twitter: https://twitter.com/CafedeVn
#Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
#Pinterest: https://www.pinterest.com/cafedevvn/
#YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
# -----------------------------------------------------------


# Python code to illustrate how double  
# underscore at the beginning works 
class Cafedev: 
    def _single_method(self): 
        pass
    def __double_method(self): # for mangling 
        pass
class Pyth(Cafedev): 
    def __double_method(self): # for mangling 
        pass

4. __dấu gạch dưới kép hàng đầu và dấu gạch dưới kép hàng cuối__

Có một trường hợp khác về dấu gạch dưới kép hàng đầu và và hàng cuối. Chúng ta tuân theo điều này trong khi sử dụng các biến hoặc phương thức đặc biệt (được gọi là phương thức magic), chẳng hạn như__len__, __init__. Các phương thức này cung cấp các tính năng cú pháp đặc biệt cho các tên. Ví dụ: __file__ chỉ ra vị trí của tệp Python, __eq__ được thực thi khi biểu thức a == b được thực thi.
Lấy ví dụ:


# Python code to illustrate double leading and  
# double trailing underscore works 
class Cafedev: 
  
    # '__init__' for initializing, this is a 
    # special method   
    def __init__(self, ab):  
        self.ab = ab 
  
    # custom special method. try not to use it 
    def __custom__(self):  
        pass

Nguồn và Tài liệu tiếng anh tham khảo:

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!