__ biến __ trong Python là gì?

Dấu gạch dưới hoặc gạch dưới (

for _ in range(5):
print("Hello world")
9) phục vụ nhiều mục đích trong Python và tôi đã nhầm lẫn về một số khía cạnh của từng mục đích trước khi bắt đầu bài viết này. Tôi đã đưa ra các giả định, đọc thông tin không chính xác và thậm chí nhận được một câu chuyện chưa hoàn chỉnh từ một lớp Python trực tuyến mà tôi đã tham gia

Trong bài viết này, tôi sẽ trình bày cách sử dụng dấu gạch dưới và cho bạn lời khuyên rất thiên vị của tôi về cách xử lý nó

Trong bài viết này, tôi sẽ đề cập đến những cách sử dụng sau của

for _ in range(5):
print("Hello world")
9

  • Nó có thể được sử dụng như một biến tạm thời trong các vòng lặp và câu lệnh gán
  • Cả dấu gạch dưới đơn (_______0_______9) và dấu gạch dưới kép (
    for _ in range(5):
    print(_)
    2) đều có thể thêm vào trước một tên biến lớp để chỉ ra rằng biến đó phải ở chế độ riêng tư. Nó có giữ các biến của bạn ở chế độ riêng tư không?
  • Nó có thể thêm tên chức năng để chỉ ra một chức năng nên riêng tư. Dấu gạch dưới có giữ chức năng của bạn ở chế độ riêng tư không?
1. Dấu gạch dưới dưới dạng Biến tạm thời

for _ in range(5):
print("Hello world")
9 có thể được sử dụng thay cho biến "giả" cả trong vòng lặp và câu lệnh gán khi một hàm trả về nhiều giá trị và bạn muốn bỏ qua một hoặc nhiều giá trị trong số đó

Sử dụng trong vòng lặp

Nếu bạn cần Python thực hiện điều gì đó năm lần, cách rõ ràng nhất là sử dụng một biến giả trong vòng lặp for, như minh họa ở đây. Khi tôi đang sử dụng một biến giả, tôi khéo léo gọi nó là…

for _ in range(5):
print(_)
4. Nhược điểm của cú pháp này được hiển thị bên dưới là tôi đã phải tạo một tên biến và hy vọng bất kỳ ai đọc mã của tôi đều hiểu rõ rằng tôi sẽ không bao giờ sử dụng lại
for _ in range(5):
print(_)
4

Dễ dàng nhận thấy điều đó trong đoạn mã ngắn này, nhưng nếu vòng lặp dài hơn và phức tạp hơn thì nó sẽ ít rõ ràng hơn

for dummy in range(5):
print("Hello world")

Tôi có thể sử dụng

for _ in range(5):
print("Hello world")
9 để thay thế. Đoạn mã bên dưới sử dụng
for _ in range(5):
print("Hello world")
9 để đạt được kết quả tương tự đồng thời báo hiệu cho bất kỳ ai đang đọc mã rằng tôi không có ý định sử dụng biến điều khiển vòng lặp ở bất kỳ đâu trong mã của mình

for _ in range(5):
print("Hello world")

Tôi thích cú pháp này và khuyến khích người khác sử dụng nó. Tuy nhiên, tôi không nhận ra rằng Python theo dõi giá trị của

for _ in range(5):
print("Hello world")
9 giống như bất kỳ biến nào khác. Hãy xem xét đoạn mã dưới đây;

for _ in range(5):
print(_)

Dấu gạch dưới thậm chí hoạt động trong một vòng lặp lồng nhau, nhưng việc theo dõi giá trị của biến

for _ in range(5):
print("Hello world")
9 trở nên khó hiểu hơn nhiều. Hãy xem xét vòng lặp này dưới đây. Bạn nghĩ mã này sẽ tạo ra cái gì?

for _ in ['A','B','C']:
print(_, end=": ")
for _ in range(4):
print(_, end=",") # what will this line print?
print() # newline

Đây là đầu ra từ đoạn mã trên

A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,

Có thể đầu ra ở trên không làm bạn ngạc nhiên, nhưng nó làm tôi ngạc nhiên. Bạn nghĩ giá trị nào mà

for _ in range(5):
print("Hello world")
9 đại diện khi các vòng lặp for lồng nhau hoàn tất?

for _ in ['A','B','C']:
pass
for _ in range(4):
pass
print(_) # what will this line print?

Tôi rất ngạc nhiên khi mã ở trên được in

for _ in ['A','B','C']:
print(_, end=": ")
for _ in range(4):
print(_, end=",") # what will this line print?
print() # newline
4. Tôi mong đợi nó không hợp lệ hoặc in
for _ in ['A','B','C']:
print(_, end=": ")
for _ in range(4):
print(_, end=",") # what will this line print?
print() # newline
5. Những gì đang xảy ra thực sự khá đơn giản. Mỗi lần lặp của vòng lặp for đang gán
for _ in range(5):
print("Hello world")
9 cho giá trị tiếp theo trong trình vòng lặp. Vòng lặp for bên ngoài chỉ đơn giản gán
for _ in range(5):
print("Hello world")
9 cho giá trị tiếp theo trong
for _ in ['A','B','C']:
print(_, end=": ")
for _ in range(4):
print(_, end=",") # what will this line print?
print() # newline
8 và vòng lặp for bên trong gán
for _ in range(5):
print("Hello world")
9 cho giá trị tiếp theo trong trình vòng lặp
A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
0

Sự nhầm lẫn này dẫn tôi đến lời khuyên đầu tiên

Không bao giờ sử dụng dấu gạch dưới làm đầu vào cho một chức năng hoặc thao tác. Nếu bạn cần theo dõi một biến, hãy dành thời gian đặt cho nó một cái tên mô tả

Bỏ qua giá trị trả về

Một số hàm Python trả về nhiều giá trị, nhưng tôi thường không cần tất cả các giá trị đó.

for _ in range(5):
print("Hello world")
9 chỉ ra rằng tôi đang bỏ qua giá trị đó. Giả sử chúng ta có một hàm trả về giá trị trung bình, chế độ và độ lệch chuẩn của tập dữ liệu, nhưng hiện tại chúng ta chỉ quan tâm đến độ lệch chuẩn. Chúng ta có thể viết như sau

_, _, stdev = myfunction(large_dataset)

Đoạn mã trên cho bất kỳ ai đọc mã của tôi biết rằng tôi chỉ định sử dụng một trong ba giá trị được trả về bởi

A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
2. Tôi thích cú pháp này hơn là khai báo thêm hai biến không bao giờ được sử dụng. Tuy nhiên, đằng sau hậu trường, Python lưu trữ giá trị của
for _ in range(5):
print("Hello world")
9 — nhưng giá trị nào?

_, _, stdev = myfunction(large_dataset)
print(_) # what will this line print?

Đoạn mã trên sẽ hiển thị giá trị thứ hai được trả về bởi

A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
2. Tôi không biết điều gì sẽ xảy ra cho đến khi tôi thử nghiệm nó trong Python REPL như thế này

>>> _, _, stdev = (1, 2, 3)
>>> print(_)
2

Sự nhầm lẫn này khiến tôi phải sửa lại lời khuyên mà tôi đã đưa ra trước đó một chút

Sử dụng dấu gạch dưới để bỏ qua một giá trị được trả về bởi hàm. Không bao giờ sử dụng dấu gạch dưới làm đầu vào cho một chức năng hoặc hoạt động. Nếu bạn cần theo dõi một biến, hãy dành thời gian đặt cho nó một cái tên mô tả

2. Dấu gạch dưới để chỉ ra các thuộc tính của lớp là riêng tư

Sử dụng các tín hiệu gạch dưới cho những người đọc và sử dụng mã, bạn có ý định đặt một biến ở chế độ riêng tư, nhưng thật đáng buồn là Python không thực thi ý định của bạn. Hãy xem xét lớp Python vô lý sau đây định nghĩa hai biến cục bộ, một biến được thêm vào trước bởi một dấu gạch dưới và biến kia có hai dấu gạch dưới

class MyClass:
def __init__(self):
self._myprivate = 12
self.__myreallyprivate = 42

Bất kỳ ai sử dụng lớp này đều có thể dễ dàng truy cập trực tiếp các biến này, mặc dù tôi dự định đặt các biến đó ở chế độ riêng tư. Python xử lý dấu gạch dưới đơn và dấu gạch dưới kép khác nhau (tôi sẽ giải thích điều đó ngay sau đây), nhưng không có cách nào trong Python thực sự đặt một biến lớp ở chế độ riêng tư như bạn có thể làm trong Java hoặc C++. Hai dòng mã sau đây sẽ chỉ ra rằng cả hai biến đều có thể được đọc và ghi trực tiếp

for _ in range(5):
print("Hello world")
0

Danh sách

A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
6 của thể hiện lớp cho thấy rằng sự khác biệt duy nhất giữa
A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
7 (dấu gạch dưới đơn) và
A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
8 (dấu gạch dưới kép) là
A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
8 hơi bị xáo trộn. Tôi có thể ghi đè lên cả hai biến mà tác giả dự định ban đầu là riêng tư như thế này

for _ in range(5):
print("Hello world")
1

Có lẽ bạn đang thắc mắc mục đích che giấu của

A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
8 có thể là gì nếu nó có thể dễ dàng được phát hiện bằng một
A: 0,1,2,3,
B: 0,1,2,3,
C: 0,1,2,3,
6 đơn giản hoặc bằng cách đọc tài liệu Python. Việc che giấu này có ích khi bạn tạo các lớp con có cùng tên biến cục bộ

Tôi sẽ minh họa điều này bằng một ví dụ đơn giản hơn về lớp cha và lớp con mà cả hai đều triển khai biến

for _ in ['A','B','C']:
pass
for _ in range(4):
pass
print(_) # what will this line print?
2. Xem xét các định nghĩa lớp sau

for _ in range(5):
print("Hello world")
2

Lớp con ở trên sẽ có hai biến bị xáo trộn. Tôi có thể hiển thị các biến đó bằng đoạn mã sau

for _ in range(5):
print("Hello world")
3

Những quan sát về dấu gạch dưới đơn và kép trong tên biến lớp dẫn tôi đến một số lời khuyên

Nếu bạn là tác giả của một lớp

  • Cung cấp phương thức “get” cho từng biến cục bộ mà bạn dự định người tiêu dùng trong lớp của bạn sẽ đọc
  • Sử dụng dấu gạch dưới để chỉ ra rằng các biến nên được coi là riêng tư

Nếu bạn là người tiêu dùng của một lớp mà người khác đã viết

  • Tránh truy cập trực tiếp các biến cục bộ của lớp nếu có thể
  • Tuyệt đối tránh truy cập trực tiếp các biến lớp được thêm dấu gạch dưới vào trước bằng mọi giá. Tác giả đặt dấu gạch dưới (hoặc cặp dấu gạch dưới) ở đó là có lý do
3. Dấu gạch dưới để biểu thị các chức năng là riêng tư

Giống như với các biến lớp,

for _ in range(5):
print("Hello world")
9 được sử dụng để báo hiệu ý định đặt một hàm ở chế độ riêng tư, nhưng Python cũng không thực thi điều này. Hãy xem xét một tệp Python có tên
for _ in ['A','B','C']:
pass
for _ in range(4):
pass
print(_) # what will this line print?
4 với định nghĩa hàm sau

for _ in range(5):
print("Hello world")
4

Nếu tôi nhập mô-đun Python này bằng một câu lệnh nhập chung như

for _ in ['A','B','C']:
pass
for _ in range(4):
pass
print(_) # what will this line print?
5, thì tôi vẫn có thể dễ dàng truy cập các mô-đun mà tôi đã cố gắng đánh dấu là riêng tư. Đó hoàn toàn không phải là những gì tác giả của hàm
for _ in ['A','B','C']:
pass
for _ in range(4):
pass
print(_) # what will this line print?
6 dự định

for _ in range(5):
print("Hello world")
5

Bất kỳ chức năng nào - ngay cả những chức năng riêng tư - đều có thể được nhập một cách rõ ràng, như được hiển thị bên dưới. Một lần nữa, đây hoàn toàn không phải là ý định của tác giả hàm

for _ in ['A','B','C']:
pass
for _ in range(4):
pass
print(_) # what will this line print?
6

for _ in range(5):
print("Hello world")
6

Tôi thậm chí có thể tạo bí danh cho chức năng riêng tư, vì vậy tôi không bị nhắc nhở liên tục rằng tôi đang sử dụng chức năng riêng tư

for _ in range(5):
print("Hello world")
7

Thật thú vị, lần duy nhất chức năng riêng tư không được nhập là khi ký tự đại diện được sử dụng, nhưng các nguyên tắc về kiểu dáng không khuyến khích sử dụng ký tự đại diện vì nó có thể tạo ra xung đột hoặc nhầm lẫn trong không gian tên

for _ in range(5):
print("Hello world")
8

Bất kể những gì Python cho phép và không cho phép, lời khuyên cuối cùng của tôi là

Mặc dù Python không ngăn bạn làm như vậy, nhưng hãy tránh nhập một hàm đã được đánh dấu là riêng tư

Suy nghĩ cuối cùng

Tất cả lời khuyên của tôi về

for _ in range(5):
print("Hello world")
9 đều tập trung vào việc báo hiệu ý định của bạn khi viết mã và tôn trọng ý định của người khác khi sử dụng mã của họ. Tuy nhiên, tôn trọng ý định của các tác giả khác hoàn toàn không phải là lịch sự. Lời khuyên này là về việc bảo vệ chính bạn

Các ví dụ tôi đưa ra trong bài viết này rất đơn giản và dễ làm theo. Khi bạn sử dụng mã phức tạp hơn, có thể có những hành vi mà bạn không lường trước được. Hàm riêng tư hoặc biến riêng tư có thể hoạt động khác với mong đợi của bạn trong một số trường hợp góc

Hơn nữa, việc triển khai các biến hoặc chức năng đó có thể thay đổi trong các phiên bản mã trong tương lai. Rốt cuộc, tác giả của mã đó đã đánh dấu chúng là riêng tư và do đó có thể tự do thay đổi chúng bất kỳ lúc nào

__ biến __ có nghĩa là gì trong Python?

__var__. hai biến có dấu gạch dưới ở đầu và ở cuối (ít nhất hai dấu gạch dưới ở đầu và ở cuối). Còn được gọi là kẻ ngu xuẩn. Quy ước đặt tên này được sử dụng bởi python để xác định các biến nội bộ. Tránh sử dụng quy ước này để tránh xung đột tên có thể phát sinh với bản cập nhật python.

Hàm __ __ có nghĩa là gì trong Python?

Trong Python, việc sử dụng dấu gạch dưới trong tên hàm cho biết rằng hàm này dành cho mục đích sử dụng nội bộ và người dùng không nên gọi trực tiếp. It is a convention used to indicate that the function is "private" and not part of the public API of the module.

Biến __ name __ tích hợp sẵn trong Python là gì?

__name__ là một biến tích hợp đánh giá theo tên của mô-đun hiện tại . Do đó, nó có thể được sử dụng để kiểm tra xem tập lệnh hiện tại đang được chạy riêng hay được nhập ở nơi khác bằng cách kết hợp tập lệnh đó với câu lệnh if, như minh họa bên dưới. Xem xét hai tệp riêng biệt File1 và File2.

__ tên __ == '__ chính __' trong Python là gì?

Trong Python, tên đặc biệt __main__ được sử dụng cho hai cấu trúc quan trọng. tên môi trường cấp cao nhất của chương trình , có thể kiểm tra bằng biểu thức __name__ == '__main__'; . __chính__. py trong các gói Python.