Bây giờ bạn đã biết sự khác biệt giữa cách Python xử lý các chế độ thực thi khác nhau, sẽ rất hữu ích nếu bạn biết những phương pháp hay nhất nào bạn có thể triển khai. Bạn sẽ tìm hiểu về bốn phương pháp hay nhất mà bạn có thể sử dụng để đảm bảo rằng mã của bạn có thể phục vụ mục đích kép
- Đặt hầu hết mã vào một chức năng hoặc lớp
- Sử dụng
__name__
để kiểm soát việc thực thi mã của bạn - Tạo một hàm có tên là
main[]
để chứa mã bạn muốn chạy - Gọi các chức năng khác từ
main[]
00. 00 Bây giờ bạn có thể thấy sự khác biệt trong cách Python xử lý các chế độ thực thi khác nhau, sẽ rất hữu ích nếu bạn biết một số phương pháp hay nhất để sử dụng. Những điều này sẽ áp dụng bất cứ khi nào bạn muốn viết mã mà bạn có thể chạy dưới dạng tập lệnh và nhập vào mô-đun khác hoặc phiên tương tác
00. 15 Bạn sẽ tìm hiểu về bốn phương pháp hay nhất để đảm bảo rằng mã của bạn có thể phục vụ mục đích kép. Đây là, một, đưa hầu hết mã vào một chức năng hoặc lớp;
00. 39 Hãy chia nhỏ chúng ra, bắt đầu với việc đưa hầu hết mã vào một hàm hoặc lớp. Hãy nhớ rằng trình thông dịch Python thực thi tất cả mã trong mô-đun khi nó nhập mô-đun
00. 49 Đôi khi mã bạn viết sẽ có tác dụng phụ mà bạn muốn người dùng kiểm soát, chẳng hạn như chạy một phép tính mất nhiều thời gian hoặc ghi vào tệp trên đĩa hoặc in thông tin làm lộn xộn thiết bị đầu cuối của người dùng
01. 02 Trong những trường hợp này, bạn muốn người dùng kiểm soát việc kích hoạt việc thực thi mã này, thay vì để trình thông dịch Python thực thi mã khi nó nhập mô-đun
01. 12 Do đó, cách thực hành tốt nhất ở đây là bao gồm hầu hết mã bên trong một hàm hoặc một lớp. Điều này là do khi trình thông dịch Python gặp các từ khóa def
hoặc class
, nó chỉ lưu trữ các định nghĩa này để sử dụng sau này và nó không thực sự thực thi chúng cho đến khi bạn ra lệnh cho nó.
01. 29 Hãy xem qua một ví dụ. Ở đây, chúng tôi có một tệp mà chúng tôi gọi là best_practices_1.py
để chứng minh ý tưởng này. Trong mã này, trước tiên bạn nhập __name__
0 từ mô-đun __name__
1. __name__
0 tạm dừng trình thông dịch trong bao nhiêu giây mà bạn đưa ra làm đối số và sẽ tạo ra một hàm mất nhiều thời gian để chạy trong ví dụ này
01. 52 Tiếp theo, bạn sử dụng __name__
3 để in một câu mô tả mục đích của đoạn mã này. Sau đó, bạn định nghĩa một hàm có tên là __name__
4 thực hiện năm việc. Đầu tiên, nó in một số đầu ra để cho người dùng biết rằng quá trình xử lý dữ liệu đang bắt đầu
02. 05 Sau đó, nó sửa đổi dữ liệu đầu vào. Tiếp theo, nó tạm dừng thực thi trong 15 giây bằng cách sử dụng chức năng __name__
0. Sau đó, nó in một số đầu ra để thông báo cho người dùng rằng quá trình xử lý đã kết thúc và cuối cùng, nó trả về dữ liệu đã sửa đổi
02. 19 Bây giờ, hãy xem điều gì sẽ xảy ra khi bạn thực thi tệp này dưới dạng tập lệnh trên dòng lệnh. Trình thông dịch Python sẽ thực thi các dòng __name__
7 và __name__
3 nằm ngoài định nghĩa hàm, sau đó nó sẽ tạo định nghĩa của hàm có tên là __name__
4
02. 35 Sau đó, tập lệnh sẽ thoát mà không cần làm gì thêm, vì tập lệnh không có bất kỳ mã nào thực thi __name__
4. Đây là kết quả của việc chạy tệp này dưới dạng tập lệnh
02. 45 Đầu ra mà chúng ta có thể thấy ở đây là kết quả của câu lệnh in đầu tiên. Lưu ý rằng việc nhập từ __name__
1 và xác định __name__
4 không tạo ra kết quả nào
02. 55 Cụ thể, đầu ra của các cuộc gọi đến __name__
3 nằm trong định nghĩa của __name__
4 không được in. Khi bạn nhập tệp này vào một phiên tương tác hoặc một mô-đun khác, trình thông dịch Python sẽ thực hiện chính xác các bước giống như khi nó thực thi tệp dưới dạng tập lệnh. Sau khi trình thông dịch Python nhập tệp, bạn có thể sử dụng bất kỳ biến, lớp hoặc hàm nào được xác định trong mô-đun mà bạn đã nhập. Để chứng minh điều này, chúng tôi sẽ sử dụng trình thông dịch tương tác Python
03. 24 Chúng ta sẽ bắt đầu trình thông dịch tương tác và sau đó chúng ta sẽ gõ main[]
5. Đầu ra duy nhất chúng ta có thể thấy là từ lệnh gọi __name__
3 đầu tiên được xác định bên ngoài __name__
4. Nhập từ __name__
1 và xác định __name__
4 không tạo ra kết quả nào, giống như khi bạn thực thi mã từ dòng lệnh
03. 44 Vậy, nếu bạn muốn __name__
4 thực thi khi bạn chạy tập lệnh từ dòng lệnh chứ không phải khi trình thông dịch Python nhập tệp thì sao?
04. 03 Bạn có thể sửa đổi tệp của mình hoặc giống như tôi đã làm ở đây, tôi đã tạo một tệp mới có tên là main[]
5 để thêm mã này vào tập lệnh. Trong mã này, chúng tôi đã thêm một câu lệnh có điều kiện để kiểm tra giá trị của __name__
04. 17 Điều kiện này sẽ ước lượng thành _________ 27 khi ________ 1 bằng chuỗi ________ 24
04. 23 Hãy nhớ rằng giá trị đặc biệt của main[]
4 cho biến __name__
có nghĩa là trình thông dịch Python đang thực thi tập lệnh của bạn và không nhập tập lệnh đó. Bên trong khối điều kiện, bạn đã thêm bốn dòng mã. Ở dòng 13 và 14, bạn đang tạo một biến có tên là __name__
2 để lưu trữ dữ liệu mà bạn đã lấy từ trang web và in nó. Ở dòng 15, bạn đang xử lý dữ liệu này. Và ở dòng 16, bạn đang in dữ liệu đã sửa đổi
04. 53 Bây giờ, hãy chạy tập lệnh mới của chúng ta từ dòng lệnh để xem đầu ra sẽ thay đổi như thế nào
05. 02 Đầu tiên, đầu ra hiển thị kết quả của cuộc gọi __name__
3 bên ngoài __name__
4. Sau đó, giá trị của __name__
2 được in ra
05. 10 Điều này xảy ra vì biến __name__
có giá trị là main[]
4 khi trình thông dịch Python thực thi tệp dưới dạng tập lệnh, vì vậy câu lệnh điều kiện được đánh giá là main[]
7. Tiếp theo, tập lệnh gọi hàm __name__
4 của chúng tôi và chuyển __name__
2 vào để sửa đổi
05. 27 Khi __name__
4 thực thi, nó sẽ in một số thông báo trạng thái ra đầu ra. Cuối cùng, giá trị của main[]
2 được in ra. Bây giờ, hãy kiểm tra điều gì sẽ xảy ra khi bạn nhập tệp từ trình thông dịch tương tác hoặc mô-đun khác
05. 41 Lưu ý rằng bạn có hành vi tương tự như trước khi bạn thêm câu lệnh điều kiện vào cuối tệp. Điều này là do biến __name__
có giá trị main[]
4, vì vậy Python không thực thi mã bên trong khối, bao gồm cả __name__
4, vì câu lệnh điều kiện được đánh giá là main[]
6
06. 00 Bây giờ bạn có thể viết mã Python có thể chạy từ dòng lệnh dưới dạng tập lệnh và được nhập mà không có tác dụng phụ không mong muốn. Tiếp theo, bạn sẽ tìm hiểu về cách viết mã của mình để giúp các lập trình viên Python khác dễ dàng làm theo ý của bạn. Nhiều ngôn ngữ, chẳng hạn như C và Java và một số ngôn ngữ khác, định nghĩa một chức năng đặc biệt phải được gọi là main[]
mà hệ điều hành tự động gọi khi thực thi chương trình đã biên dịch
06. 23 Hàm này thường được gọi là điểm vào vì nó là nơi thực thi vào chương trình. Ngược lại, Python không có chức năng đặc biệt đóng vai trò là điểm vào của tập lệnh. Bạn thực sự có thể cung cấp cho điểm vào trong tập lệnh Python bất kỳ tên nào bạn muốn
06. 36 Mặc dù Python không gán bất kỳ ý nghĩa nào cho một hàm có tên là main[]
, nhưng cách tốt nhất ở đây là đặt tên cho hàm đầu vào là main[]
.
06. 45 Bằng cách đó, bất kỳ lập trình viên nào khác khi đọc tập lệnh của bạn đều biết ngay rằng chức năng này là điểm bắt đầu của mã hoàn thành nhiệm vụ chính của tập lệnh. Ngoài ra, main[]
phải chứa bất kỳ mã nào mà bạn muốn chạy ở nơi trình thông dịch Python thực thi tệp
07. 00 Điều này tốt hơn là đặt mã trực tiếp vào khối điều kiện vì người dùng có thể sử dụng lại main[]
nếu họ nhập mô-đun của bạn. Bây giờ, hãy kiểm tra phiên bản thứ ba của tập lệnh của chúng tôi để giúp hiểu khái niệm này. Trong phiên bản này, chúng tôi đã thêm định nghĩa của main[]
bao gồm mã trước đây nằm trong khối điều kiện và sau đó chúng tôi đã thay đổi khối điều kiện để nó thực thi main[]
07. 23 Nếu bạn chạy mã này dưới dạng tập lệnh hoặc nhập mã, bạn sẽ nhận được kết quả giống như trước đây. Một thực tế phổ biến khác trong Python là để hàm main[]
thực thi các hàm khác, thay vì bao gồm mã hoàn thành tác vụ trong main[]
07. 36 Điều này đặc biệt hữu ích khi bạn soạn nhiệm vụ tổng thể của mình từ một số nhiệm vụ phụ nhỏ hơn có thể thực hiện độc lập. Ví dụ: bạn có thể có một tập lệnh thực hiện như sau. đọc tệp từ một nguồn có thể là cơ sở dữ liệu, tệp trên đĩa hoặc API web;
07. 57 Nếu bạn triển khai từng nhiệm vụ phụ này trong các chức năng riêng biệt thì bạn hoặc người dùng sẽ dễ dàng sử dụng lại một số bước và bỏ qua những bước bạn không muốn. Sau đó, bạn có thể tạo quy trình công việc mặc định trong main[]
và bạn có thể tận hưởng cả hai thế giới tốt nhất
08. 11 Việc có áp dụng cách làm này vào quy tắc của bạn hay không là quyết định từ phía bạn. Việc chia nhỏ công việc thành nhiều chức năng giúp việc sử dụng lại dễ dàng hơn nhưng lại làm tăng khó khăn cho người khác đang cố diễn giải mã của bạn vì họ phải thực hiện theo một số bước nhảy trong luồng chương trình
08. 26 Vì vậy, hãy xem phiên bản cuối cùng của kịch bản của chúng ta có tên là main[]
7. Bước qua mã này, chín dòng đầu tiên của tệp có cùng nội dung mà chúng có trước đó
08. 37 Định nghĩa hàm thứ hai ở dòng 11 tạo và trả về một số dữ liệu mẫu, định nghĩa hàm thứ ba ở dòng 16 mô phỏng việc ghi dữ liệu đã sửa đổi vào cơ sở dữ liệu. Trên dòng 20, main[]
được định nghĩa. Trong ví dụ này, chúng tôi đã sửa đổi main[]
để nó lần lượt gọi các chức năng đọc dữ liệu, xử lý dữ liệu và ghi dữ liệu. Đầu tiên, __name__
2 được tạo từ def
1
09. 04 __name__
2 này được chuyển đến __name__
4, trả về main[]
2. Cuối cùng, main[]
2 được chuyển vào def
6
09. 13 Hai dòng cuối cùng của tập lệnh là khối điều kiện kiểm tra __name__
và chạy main[]
nếu câu lệnh là main[]
7. Bây giờ, hãy chạy toàn bộ quy trình xử lý từ dòng lệnh. Bạn có thể thấy rằng trình thông dịch Python đã thực thi main[]
, đã thực thi def
1, __name__
4 và def
6
09. 34 Tuy nhiên, bạn cũng có thể nhập tệp này và sử dụng lại __name__
4 cho một nguồn dữ liệu đầu vào khác. Trước tiên, bạn cần nhập tệp, sau đó bạn có thể đặt tên rút gọn của nó là class
5 cho mã này
09. 46 Quá trình nhập khiến trình thông dịch Python thực thi tất cả các dòng mã trong tệp. Giờ đây, class
5 đã được nhập, bạn có thể sử dụng các hàm đã nhập đó, tạo một biến có tên là __name__
2 và đặt giá trị của nó thành chuỗi class
8 thay vì đọc dữ liệu từ trang web
10. 06 Sau đó sử dụng lại các hàm __name__
4 và def
6 từ tệp. Trong trường hợp này, bạn tận dụng lợi thế của việc sử dụng lại mã thay vì xác định tất cả logic trong main[]
. Vì vậy, có khá nhiều thứ để tiếp thu, vì vậy, đây là bản tóm tắt về bốn phương pháp hay nhất chính về main[]
trong Python mà bạn vừa xem. Đầu tiên, hãy đặt đoạn mã mất nhiều thời gian để chạy hoặc có các hiệu ứng khác trên máy tính trong một hàm hoặc lớp để bạn có thể kiểm soát chính xác thời điểm đoạn mã đó được thực thi
10. 39 Hai, sử dụng các giá trị khác nhau của __name__
để xác định ngữ cảnh và thay đổi hành vi của mã của bạn bằng một câu lệnh có điều kiện. Thứ ba, bạn nên đặt tên cho hàm đầu vào của mình là main[]
để truyền đạt mục đích của hàm, mặc dù Python không gán bất kỳ ý nghĩa đặc biệt nào cho một hàm có tên là main[]
. Và cuối cùng, số bốn, nếu bạn muốn sử dụng lại chức năng từ mã của mình, hãy xác định logic trong các hàm bên ngoài main[]
và gọi các hàm đó từ bên trong main[]
. Trong bài học tiếp theo, bạn sẽ xem lại mọi thứ bạn đã học trong khóa học này
Gregory Klassen vào ngày 10 tháng 3 năm 2020
Có phải tmux hoặc một số thiết lập đầu cuối khác mà bạn sử dụng trong bản trình bày của mình không?
Dan Bader Nhóm RP vào ngày 10 tháng 3 năm 2020
@Gregory. Tôi tin rằng đây là thiết bị đầu cuối tích hợp sẵn của trình soạn thảo VS Code. Chúng tôi có một khóa học chuyên dụng về nó ở đây. ]
mattc vào ngày 11 tháng 3 năm 2020
Điều gì xảy ra nếu bạn nhập nhiều mô-đun với hàm main[]?
SkyFox vào ngày 11 tháng 3 năm 2020
Rất thường ở đầu tệp, người ta xác định các biến cấp độ mô-đun. Điều đó có nghĩa là chúng có sẵn từ phạm vi của tập lệnh nhập không?
pallavlearn vào ngày 18 tháng 3 năm 2020
Bạn có ghi lại âm thanh và video riêng biệt hay là một lần?
Zarata vào tháng 11. 12, 2020
Cá nhân tôi đã tìm thấy một điểm nhầm lẫn [picayune[??]] ở đây. Có ít nhất hai tuyên bố được đưa ra mà tôi tin rằng có lẽ đúng về mặt kỹ thuật, nhưng về phía tôi mà không nhận ra thêm thì dường như mâu thuẫn với những điểm khác đã được đưa ra. “Mặc dù Python không gán bất kỳ ý nghĩa nào cho một hàm có tên là ‘main’…” và “Chúng tôi thực sự có thể đặt cho điểm vào trong tập lệnh Python bất kỳ tên nào chúng tôi muốn…”
Vấn đề của tôi là thông số ngôn ngữ đó. được trích dẫn trong phần trước của mô-đun này trên bề mặt đã ngụ ý điều gì đó “đặc biệt” về các chữ cái “chính”. “__name__ của mô-đun được đặt bằng '__main__' khi được đọc từ đầu vào tiêu chuẩn, tập lệnh hoặc từ lời nhắc tương tác. tài liệu. con trăn. org/3/library/__main__. html“
Dài ngắn. điều còn thiếu đối với tôi là cuối cùng tôi cũng nhận ra rằng “__main__” là một GIÁ TRỊ CHUỖI đặc biệt, KHÔNG PHẢI là một ký hiệu biến đặc biệt khác [như __name__]. Thông số kỹ thuật đang nói một giá trị Chuỗi đặc biệt “__main__” đôi khi được gán bởi ngôn ngữ cho __name__. Không có một số cơ chế [không giải thích được] thay đổi giá trị của một biến __main__ thành tên của một chức năng điểm vào
Do đó, người ta có thể viết một “điều kiện bảo vệ” [được gọi như vậy trong một tài liệu tham khảo khác] cho một điểm vào được đặt tên tùy ý là “foo” như
if __name__ == "__main__": #__main__ is a string value, NOT a
# variable symbol
foo[] #A non-conventionally-named entry point
# function
Tôi cho rằng tôi sẽ bỏ qua phần đáng xấu hổ này, đề phòng trường hợp bất kỳ ai khác có xu hướng vấp phải dây giày của chính họ cũng có câu hỏi tương tự “huh ??”