Con trăn __ tên __ là gì?

Nếu bạn đã viết mã bằng Python được một thời gian hoặc chỉ tình cờ duyệt qua các kho lưu trữ Github của Python, thì có lẽ bạn đã bắt gặp đoạn mã này

if __name__ == '__main__':
  # do something

Nó phổ biến

Trên thực tế, đây là số lần đoạn mã trên xuất hiện trong Github

Con trăn __ tên __ là gì?

hơn 18 triệu lần

Vì vậy, không cần phải quảng cáo thêm, hãy cùng nghiên cứu chính xác đoạn mã này làm gì

__name__ là gì?

__name__ chỉ đơn giản là một biến tích hợp trong Python để đánh giá tên của mô-đun hiện tại

Để hiểu đầy đủ __name__ là gì và nó được sử dụng như thế nào, hãy xem qua một loạt ví dụ

ví dụ 1

Hãy tạo một tập lệnh Python đơn giản trong một tệp có tên là test. py

# test.py
print("__name__ in test.py is set to " + __name__)

Chức năng của dòng này là nó sẽ in biến __name__ ra màn hình để chúng ta có thể kiểm tra nó

Hãy chạy tập lệnh này từ thiết bị đầu cuối và xem những gì chúng tôi nhận được

$ python test.py

Đây là đầu ra mà bạn sẽ thấy trên màn hình

$ python3 test.py
__name__ in test.py is set to __main__

Từ đó, chúng ta có thể kết luận rằng trong ví dụ này, biến __name__ đã được đặt thành giá trị chuỗi __main__

Bây giờ hãy xem một ví dụ hơi khác

ví dụ 2

Hãy tạo một tệp mới test2. py trong cùng thư mục với test. py

Trong tệp mới này, hãy nhập test để chúng ta có thể kiểm tra biến __name__ trong test. py và hãy in biến __name__ trong test2. py

# test2.py
import test

print("__name__ in test2.py is set to " + __name__)

Nếu bạn chạy test2. py từ thiết bị đầu cuối, đây là những gì bạn sẽ thấy trên màn hình của mình

$ python3 test2.py
__name__ in test.py is set to test
__name__ in test2.py is set to __main__

Hmm thú vị, vậy chuyện gì đang xảy ra vậy?

Về cơ bản, điều đang xảy ra là __name__  được đặt ở cấp độ mô-đun

Nó được đặt thành tên của mô-đun. Nói cách khác, đối với mọi mô-đun trong mã của bạn, __name__ sẽ được đặt thành tên mô-đun đó

Và đối với điểm thực thi, tập lệnh chính của Python, biến __name__ sẽ được đặt thành __main__

Điều đó thật tuyệt nhưng biến đặc biệt này được sử dụng như thế nào trong thực tế?

__name__ được sử dụng như thế nào trong các ứng dụng thực tế?

Một lý do để làm điều này là nếu bạn muốn viết một mô-đun có thể được thực thi trực tiếp hoặc có thể được nhập và sử dụng trong một mô-đun khác

Ví dụ: hãy tạo một mô-đun giả xin chào. py mà những người khác có thể nhập vào tập lệnh của riêng họ hoặc họ có thể trực tiếp thực thi nó nếu họ muốn

Đây là những gì mô-đun này phải làm

Nếu bạn trực tiếp thực thi mô-đun, thì mô-đun sẽ in Xin chào, Afternerd trên màn hình.

Tuy nhiên, nếu bạn nhập nó thay vào đó, nó sẽ cung cấp cho bạn một chức năng hello() nơi bạn có thể kiểm soát người chào hỏi.

# hello.py
def hello(name):
  print(f"Hello, {name}!")

if __name__ == '__main__':
  hello('Afternerd')

Bây giờ hãy tạo một tập lệnh chính chính. py sẽ nhập mô-đun xin chào

# main.py
from hello import hello

hello('Karim')

Bạn nghĩ điều gì sẽ xảy ra nếu chúng ta trực tiếp thực hiện lệnh hello. py?

Chúng tôi chỉ nhận được Hello, Afternerd. được in trên màn hình vì điều kiện if bên trong mô-đun hello sẽ được thỏa mãn

________số 8

Sẽ thế nào nếu chúng ta trực tiếp thực thi chính. py thay thế?

Bây giờ, chúng tôi sẽ chỉ nhận được Hello, Karim. in trên màn hình

$ python3 main.py
Hello, Karim!

Nhưng nếu chúng ta không bao gồm điều kiện if __name__ == ‘main’ trong mô-đun hello thì sao?

Nếu bạn chưa bao gồm điều kiện if trong mô-đun của mình, bạn sẽ nhận được kết quả không mong muốn này khi chạy tập lệnh chính

tên của môi trường cấp cao nhất của chương trình, có thể được kiểm tra bằng cách sử dụng biểu thức

# test.py
print("__name__ in test.py is set to " + __name__)
01;

  • tệp

    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 trong các gói Python

  • Cả hai cơ chế này đều liên quan đến các mô-đun Python; . Chúng được giải thích chi tiết dưới đây. Nếu bạn chưa quen với các mô-đun Python, hãy xem phần hướng dẫn Mô-đun để biết phần giới thiệu.

    # test.py print("__name__ in test.py is set to " + __name__)01¶

    Khi một mô-đun hoặc gói Python được nhập,

    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 được đặt thành tên của mô-đun. Thông thường, đây là tên của chính tệp Python không có phần mở rộng
    # test.py
    print("__name__ in test.py is set to " + __name__)
    05

    # test.py
    print("__name__ in test.py is set to " + __name__)
    5

    Nếu tệp là một phần của gói, thì

    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 cũng sẽ bao gồm đường dẫn của gói gốc

    # test.py
    print("__name__ in test.py is set to " + __name__)
    7

    Tuy nhiên, nếu mô-đun được thực thi trong môi trường mã cấp cao nhất, thì

    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 của nó được đặt thành chuỗi
    # test.py
    print("__name__ in test.py is set to " + __name__)
    08

    “Môi trường mã cấp cao nhất” là gì?¶

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 là tên của môi trường nơi mã cấp cao nhất được chạy. “Mã cấp cao nhất” là mô-đun Python do người dùng chỉ định đầu tiên bắt đầu chạy. Đó là "cấp cao nhất" vì nó nhập tất cả các mô-đun khác mà chương trình cần. Đôi khi “mã cấp cao nhất” được gọi là điểm vào ứng dụng

    Môi trường mã cấp cao nhất có thể là

    • phạm vi của lời nhắc tương tác

      # test.py
      print("__name__ in test.py is set to " + __name__)
      0

    • mô-đun Python được chuyển tới trình thông dịch Python dưới dạng đối số tệp

      $ python test.py
      2

    • mô-đun hoặc gói Python được chuyển tới trình thông dịch Python với đối số

      $ python test.py
      20

      $ python test.py
      4

    • Mã Python được trình thông dịch Python đọc từ đầu vào tiêu chuẩn

      $ python test.py
      5

    • Mã Python được chuyển tới trình thông dịch Python với đối số

      $ python test.py
      21

      $ python test.py
      7

    Trong mỗi tình huống này,

    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 của mô-đun cấp cao nhất được đặt thành
    # test.py
    print("__name__ in test.py is set to " + __name__)
    08

    Do đó, một mô-đun có thể khám phá xem nó có đang chạy trong môi trường cấp cao nhất hay không bằng cách kiểm tra

    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 của chính nó, điều này cho phép một thành ngữ phổ biến cho mã thực thi có điều kiện khi mô-đun không được khởi tạo từ câu lệnh nhập

    $ python3 test.py
    __name__ in test.py is set to __main__
    1

    Xem thêm

    Để có cái nhìn chi tiết hơn về cách đặt

    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 trong mọi trường hợp, hãy xem phần hướng dẫn Mô-đun .

    Cách sử dụng thành ngữ¶

    Một số mô-đun chứa mã chỉ dành cho mục đích sử dụng tập lệnh, chẳng hạn như phân tích đối số dòng lệnh hoặc tìm nạp dữ liệu từ đầu vào tiêu chuẩn. Nếu một mô-đun như thế này được nhập từ một mô-đun khác, chẳng hạn như để kiểm tra đơn vị nó, mã tập lệnh cũng sẽ vô tình thực thi

    Đây là nơi sử dụng khối mã

    $ python test.py
    26 có ích. Mã trong khối này sẽ không chạy trừ khi mô-đun được thực thi trong môi trường cấp cao nhất

    Đặt càng ít câu lệnh càng tốt vào khối bên dưới

    $ python test.py
    27 có thể cải thiện độ rõ ràng và chính xác của mã. Thông thường, một hàm có tên
    $ python test.py
    28 gói gọn hành vi chính của chương trình

    $ python3 test.py
    __name__ in test.py is set to __main__
    6

    Lưu ý rằng nếu mô-đun không đóng gói mã bên trong hàm

    $ python test.py
    28 mà thay vào đó đặt nó trực tiếp trong khối
    $ python test.py
    26, thì biến
    $ python test.py
    41 sẽ là toàn cục cho toàn bộ mô-đun. Điều này dễ xảy ra lỗi vì các chức năng khác trong mô-đun có thể vô tình sử dụng biến toàn cục thay vì tên cục bộ. Hàm
    $ python test.py
    28 giải quyết vấn đề này

    Sử dụng hàm

    $ python test.py
    28 có thêm lợi ích là bản thân hàm
    $ python test.py
    44 được tách biệt và có thể nhập ở nơi khác. Khi
    $ python test.py
    45 được nhập, các hàm
    $ python test.py
    44 và
    $ python test.py
    28 sẽ được xác định, nhưng cả hai hàm này sẽ không được gọi, bởi vì
    $ python test.py
    48

    Cân nhắc về bao bì¶

    Các hàm

    $ python test.py
    28 thường được sử dụng để tạo các công cụ dòng lệnh bằng cách chỉ định chúng làm điểm nhập cho tập lệnh bảng điều khiển. Khi điều này được thực hiện, pip sẽ chèn lời gọi hàm vào tập lệnh mẫu, trong đó giá trị trả về của
    $ python test.py
    28 được chuyển vào
    $ python test.py
    51. Ví dụ

    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    0

    Vì lệnh gọi tới

    $ python test.py
    28 được bao bọc trong
    $ python test.py
    51, nên kỳ vọng là hàm của bạn sẽ trả về một số giá trị được chấp nhận làm đầu vào cho
    $ python test.py
    51;

    Bằng cách chủ động tuân theo quy ước này, mô-đun của chúng ta sẽ có hành vi tương tự khi chạy trực tiếp (i. e.

    $ python test.py
    56) như nó sẽ có nếu sau này chúng tôi đóng gói nó dưới dạng điểm nhập tập lệnh bảng điều khiển trong gói có thể cài đặt pip

    Đặc biệt, hãy cẩn thận về việc trả về các chuỗi từ hàm

    $ python test.py
    28 của bạn.
    $ python test.py
    51 sẽ diễn giải một đối số chuỗi dưới dạng thông báo lỗi, vì vậy chương trình của bạn sẽ có mã thoát là
    $ python test.py
    59, biểu thị lỗi và chuỗi sẽ được ghi vào
    $ python test.py
    70. Ví dụ
    $ python test.py
    45 từ trước minh họa bằng cách sử dụng quy ước
    $ python test.py
    72

    Xem thêm

    Hướng dẫn sử dụng gói Python chứa một tập hợp các hướng dẫn và tài liệu tham khảo về cách phân phối và cài đặt các gói Python bằng các công cụ hiện đại

    # test.py print("__name__ in test.py is set to " + __name__)02 trong Gói Python¶

    Nếu bạn không quen với các gói Python, hãy xem phần Gói của hướng dẫn. Thông thường nhất, tệp

    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 được sử dụng để cung cấp giao diện dòng lệnh cho gói. Hãy xem xét gói giả thuyết sau đây, “bandclass”.

    # test.py
    print("__name__ in test.py is set to " + __name__)
    70

    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 sẽ được thực thi khi chính gói đó được gọi trực tiếp từ dòng lệnh bằng cờ
    $ python test.py
    20. Ví dụ

    # test.py
    print("__name__ in test.py is set to " + __name__)
    71

    Lệnh này sẽ khiến

    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 chạy. Cách bạn sử dụng cơ chế này sẽ phụ thuộc vào bản chất của gói bạn đang viết, nhưng trong trường hợp giả định này, có thể hợp lý nếu cho phép giáo viên tìm kiếm học sinh

    # test.py
    print("__name__ in test.py is set to " + __name__)
    72

    Lưu ý rằng

    $ python test.py
    78 là một ví dụ về nhập tương đối. Kiểu nhập này có thể được sử dụng khi tham chiếu các mô-đun trong một gói. Để biết thêm chi tiết, hãy xem Tham chiếu bên trong gói trong phần Mô-đun của .

    Cách sử dụng thành ngữ¶

    Nội dung của

    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 thường không được rào bằng các khối
    $ python test.py
    26. Thay vào đó, các tệp đó được giữ ngắn gọn, các chức năng để thực thi từ các mô-đun khác. Những mô-đun khác sau đó có thể dễ dàng kiểm tra đơn vị và có thể tái sử dụng đúng cách

    Nếu được sử dụng, khối

    $ python test.py
    26 sẽ vẫn hoạt động như mong đợi đối với tệp
    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 trong một gói vì thuộc tính
    # test.py
    print("__name__ in test.py is set to " + __name__)
    04 của nó sẽ bao gồm đường dẫn của gói nếu được nhập

    # test.py
    print("__name__ in test.py is set to " + __name__)
    73

    Điều này sẽ không hoạt động đối với các tệp

    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 trong thư mục gốc của một. tập tin zip mặc dù. Do đó, để đảm bảo tính nhất quán, nên ưu tiên sử dụng
    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 tối thiểu như
    $ python3 test.py
    __name__ in test.py is set to __main__
    16 được đề cập bên dưới

    Xem thêm

    Xem

    $ python3 test.py
    __name__ in test.py is set to __main__
    16 để biết ví dụ về gói có tối thiểu
    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 trong thư viện chuẩn. Nó không chứa khối
    $ python test.py
    26. Bạn có thể gọi nó bằng
    $ python3 test.py
    __name__ in test.py is set to __main__
    60

    Xem

    $ python3 test.py
    __name__ in test.py is set to __main__
    61 để biết thêm chi tiết về cờ
    $ python test.py
    20 cho trình thông dịch thực thi

    Xem

    $ python3 test.py
    __name__ in test.py is set to __main__
    63 để biết cách chạy các ứng dụng được đóng gói dưới dạng. tập tin zip. Trong trường hợp này, Python tìm tệp
    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 trong thư mục gốc của kho lưu trữ

    $ python3 test.py __name__ in test.py is set to __main__65¶

    Bất kể chương trình Python được bắt đầu với mô-đun nào, các mô-đun khác đang chạy trong cùng chương trình đó có thể nhập phạm vi của môi trường cấp cao nhất ( không gian tên) by importing the

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 module. This doesn’t import a
    # test.py
    print("__name__ in test.py is set to " + __name__)
    02 file but rather whichever module that received the special name
    # test.py
    print("__name__ in test.py is set to " + __name__)
    08.

    Đây là một mô-đun ví dụ sử dụng không gian tên

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79

    # test.py
    print("__name__ in test.py is set to " + __name__)
    74

    Ví dụ sử dụng mô-đun này có thể như sau

    # test.py
    print("__name__ in test.py is set to " + __name__)
    75

    Bây giờ, nếu chúng ta bắt đầu chương trình của mình, kết quả sẽ như thế này

    # test.py
    print("__name__ in test.py is set to " + __name__)
    76

    Mã thoát của chương trình sẽ là 1, cho biết có lỗi. Bỏ ghi chú dòng với

    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    00 sửa chương trình và bây giờ chương trình thoát với mã trạng thái 0, biểu thị thành công

    # test.py
    print("__name__ in test.py is set to " + __name__)
    77

    Lưu ý rằng việc nhập

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 không gây ra bất kỳ sự cố nào với mã cấp cao nhất chạy ngoài ý muốn dành cho việc sử dụng tập lệnh được đặt trong khối
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    02 của mô-đun
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    03. Tại sao điều này làm việc?

    Python chèn mô-đun

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 trống vào
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    05 khi khởi động trình thông dịch và điền vào mô-đun đó bằng cách chạy mã cấp cao nhất. Trong ví dụ của chúng tôi, đây là mô-đun
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    03 chạy từng dòng và nhập
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    07. Đổi lại,
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    07 nhập khẩu
    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 (thực ra là
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    03). Đó là một chu kỳ nhập khẩu. May mắn thay, vì mô-đun
    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 được điền một phần có trong
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    05, nên Python chuyển nó sang
    $ python3 test2.py
    __name__ in test.py is set to test
    __name__ in test2.py is set to __main__
    07. Xem Những cân nhắc đặc biệt đối với __main__ trong tài liệu tham khảo của hệ thống nhập để biết chi tiết về cách thức hoạt động của tính năng này.

    REPL của Python là một ví dụ khác về “môi trường cấp cao nhất”, vì vậy mọi thứ được định nghĩa trong REPL đều trở thành một phần của phạm vi

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79

    # test.py
    print("__name__ in test.py is set to " + __name__)
    78

    Lưu ý rằng trong trường hợp này, phạm vi

    # test.py
    print("__name__ in test.py is set to " + __name__)
    79 không chứa thuộc tính
    # test.py
    print("__name__ in test.py is set to " + __name__)
    706 vì nó tương tác

    __ tên __ dùng để làm gì?

    Biến __name__ (hai dấu gạch dưới trước và sau) là một biến Python đặc biệt. Nó nhận giá trị tùy thuộc vào cách chúng tôi thực thi tập lệnh chứa . Đôi khi bạn viết một tập lệnh với các chức năng cũng có thể hữu ích trong các tập lệnh khác. Trong Python, bạn có thể nhập tập lệnh đó dưới dạng mô-đun trong tập lệnh khác.

    Python __ chính __ là gì?

    __main__ là tên của môi trường chạy mã cấp cao nhất . “Mã cấp cao nhất” là mô-đun Python do người dùng chỉ định đầu tiên bắt đầu chạy. Đó là "cấp cao nhất" vì nó nhập tất cả các mô-đun khác mà chương trình cần. Đôi khi “mã cấp cao nhất” được gọi là điểm vào ứng dụng.

    _ và __ nghĩa là gì trong Python?