Các ngôn ngữ lập trình như C và C++ cho phép lập trình viên viết mã lệnh ở mức độ rất chi tiết và mang lạitốc độ thực hiện nhanh chóng. Tuy nhiên trong hầu hết các ứng dụng thực tiễn, tốc độ thực hiện không phảilà yếu tố quan trọng, và trong nhiều trường hợp, người sử dụng sẵn sàng viết mã lệnh bằng một ngôn ngữcấp cao hơn. Chẳng hạn, với các chương trình xử lí file văn bản, đơn vị cơ bản trong CC++ là kí tự, còn vớinhững ngôn ngữ như Perl và Python thì đó là các dòng văn bản và các từ trong mỗi dòng. Dĩ nhiên là có thểxử lí các dòng văn bản và các từ trong CC++, nhưng ta cần cố gắng nhiều hơn nếu muốn đạt được một kếtquả tương tự.
Tài liệu hướng dẫn nhanh ngắn gọn sử dụng ngôn ngữ Python Norman Matloff University of California, Davis c 2003-2006, N Matloff 26 tháng năm 2006 Mục lục Khái quát chung 1.1 Các ngôn ngữ script 1.2 Tại nên dùng Python? Hướng dẫn sử dụng tài liệu 2.1 Kiến thức cần có 2.2 Hướng tiếp cận 2.3 Những phần cần đọc đọc Một ví dụ hướng dẫn phút 3.1 Mã lệnh chương trình ví dụ 3.2 Kiểu liệu dạng danh sách (list) 3.3 Khối lệnh Python 3.4 Python có chế độ gõ lệnh tương tác 3.5 Dùng Python máy tính bỏ túi Một ví dụ hướng dẫn 10 phút 4.1 Mã lệnh ví dụ 4.2 Giới thiệu xử lí file 10 Khai báo hay không khai báo, Phạm vi, Hàm, v.v 10 5.1 Không có phần khai báo 10 5.2 Biến toàn cục biến cục 11 Một số hàm có sẵn Python 11 6.1 Các chuỗi so với giá trị số 12 6.2 Danh sách (mảng) 13 6.2.1 Các Tuple 15 6.2.2 Chuỗi kí tự 15 6.2.3 Sắp xếp 16 6.2.4 Tác dụng name 18 Lập trình hướng đối tượng (Object-Oriented Programming), OOP 20 7.1 Từ khóa “self” 21 7.2 Các biến thực thể 21 7.2.1 Tạo lớp xóa lớp 22 7.3 Các phương thức với thực thể 22 7.4 Docstring 23 7.5 Các phương thức lớp 23 7.6 Các lớp suy diễn 24 7.7 Một lưu ý lớp 24 Tầm quan trọng việc hiểu tham chiếu đối tượng 24 So sánh đối tượng 26 10 Các mô-đun gói chương trình 27 10.1 Mô-đun 27 10.1.1 Ví dụ mã lệnh chương trình 27 10.1.2 Lệnh import làm việc nào? 28 10.1.3 Mã lệnh biên dịch 29 10.1.4 Các vấn đề hỗn hợp 29 10.1.5 Chú ý biến toàn cục 29 10.2 Che giấu liệu 30 10.3 Các gói chương trình 31 11 Xử lí lỗi 32 12 Phần hỗn hợp 32 12.1 Chạy mã lệnh Python mà trực tiếp mở thông dịch 32 12.2 In kết dấu xuống dòng dấu trống 33 12.3 Định dạng chuỗi 33 12.4 Các tham biến có tên hàm 34 13 Ví dụ cấu trúc liệu Python 35 13.1 Sử dụng kiểu cú pháp đặc biệt 37 14 Các đặc điểm lập trình hàm 38 14.1 Các hàm Lambda 38 14.2 Mapping 38 14.3 Lọc 40 14.4 List Comprehension 40 14.5 Chiết giảm 40 15 Các biểu thức phát sinh 41 A Gỡ lỗi 42 A.1 Công cụ gỡ lỗi sẵn có Python, PDB 42 A.1.1 Dạng 42 A.1.2 Lưu ý lệnh Next Step 44 A.1.3 Sử dụng Macro PDB 44 A.1.4 Sử dụng dict 45 A.2 Sử dụng PDB với DDD 45 A.2.1 Chuẩn bị 46 A.2.2 Khởi động DDD mở chương trình 46 A.2.3 Các điểm dừng 46 A.2.4 Chạy chương trình nguồn bạn 47 A.2.5 Theo dõi biến 47 A.2.6 Các vấn đề hỗn hợp 47 A.2.7 Một số hỗ trợ gỡ lỗi có sẵn Python 47 A.2.8 Thuộc tính dict 48 A.2.9 Hàm id() 48 A.2.10 Các công cụ / IDE gỡ lỗi khác 48 A.3 Tài liệu trực tuyến 49 A.3.1 Hàm dir() 49 A.3.2 Hàm help() 50 A.4 Giải thích biện pháp xử lí biến lớp cũ 51 A.5 Đưa tất biến toàn cục vào lớp 53 Khái quát chung 1.1 Các ngôn ngữ script Các ngôn ngữ lập trình C C++ cho phép lập trình viên viết mã lệnh mức độ chi tiết mang lại tốc độ thực nhanh chóng Tuy nhiên hầu hết ứng dụng thực tiễn, tốc độ thực yếu tố quan trọng, nhiều trường hợp, người sử dụng sẵn sàng viết mã lệnh ngôn ngữ cấp cao Chẳng hạn, với chương trình xử lí file văn bản, đơn vị C/C++ kí tự, với ngôn ngữ Perl Python dòng văn từ dòng Dĩ nhiên xử lí dòng văn từ C/C++, ta cần cố gắng nhiều muốn đạt kết tương tự Thực thuật ngữ “scripting language” (ngôn ngữ kịch bản) chưa định nghĩa thức, sau số đặc điểm nó: • sử dụng thường xuyên lĩnh vực quản trị hệ thống, lập trình Web “mô hình hoá hệ thống” tinh chỉnh phần mềm theo yêu cầu người sử dụng trình sản xuất phần mềm • khai báo biến cách tự nhiên (với biến nguyên, dấu phẩy động chuỗi kí tự thường khác biệt) Các mảng trộn lẫn kiểu biến khác nhau, chẳng hạn kiểu nguyên kiểu chuỗi kí tự Các hàm trả giá trị kiểu mảng (thay scalar) Các kiểu mảng dùng làm số đếm vòng lặp v.v • nhiều phép tính cấp cao xây dựng sẵn ngôn ngữ, chẳng hạn kết nối chuỗi kí tự push/pop stack • thông dịch thay biên dịch thành ngôn ngữ máy 1.2 Tại nên dùng Python? Ngày ngôn ngữ kịch phổ biến có lẽ Perl Tuy vậy, có nhiều người, có tác giả, ưa chuộng Python ngôn ngữ rõ ràng tinh tế Đối với người phát triển hệ thống Google Python ngôn ngữ quen thuộc Những người ủng hộ Python, thường gọi Pythonista, cho ngôn ngữ sáng tiện dụng đến mức ta dùng cho khâu lập trình không riêng viết script Họ tin Python hay C C++.1 Cá nhân cho người ta đề cao C++; số thành phần ngôn ngữ không khớp với Java ngôn ngữ hay hơn, yêu cầu biến phải có kiểu định Đặc điểm này, theo tôi, tăng độ phức tạp việc lập trình Tôi vui thấy Eric Raymond, người tiếng giới phát triển phần mềm mã nguồn mở khẳng định điều tương tự C++, Java Python Một ngoại lệ cần nhắc lại ta không xét đến chương trình yêu cầu tốc độ cao Hướng dẫn sử dụng tài liệu 2.1 Kiến thức cần có Bất kì với chút kinh nghiệm lập trình tiếp cận nội dung trình bày tài liệu Tài liệu mở đầu với phần Hướng đối tượng 7, thuận tiện cho người có kiến thức ngôn ngữ lập trình hướng đối tượng C++ Java Nếu thiếu phần kiến thức này, bạn đọc phần này, phải chậm so với người biết C++ Java; bạn cần nắm ví dụ thay thuật ngữ Sẽ có đôi chỗ trình bày riêng máy bạn sử dụng hệ điều hành Unix Nhưng thực tế kiến thức Unix không cần thiết bạn dùng Python Windows Macintosh không riêng Unix 2.2 Hướng tiếp cận Hướng tiếp cận ta tương đối khác so với phần lớn sách (hay trang web hướng dẫn) Python Cách tiếp cận thông thường trình bày chi tiết từ đầu đến cuối Chẳng hạn việc liệt kê hết tất giá trị tham số câu lệnh Python Trong tài liệu tránh dùng cách Một lần nữa, mục tiêu cho phép người đọc nhanh chóng nắm bắt tảng Python, từ tìm hiểu sâu vào vấn đề cụ thể theo nhu cầu 2.3 Những phần cần đọc đọc Theo tôi, bạn nên bắt đầu đọc phần key, sau sử dụng thử Python Trước hết thử nghiệm thao tác với dấu nhắc lệnh Python (Phần dấu nhắc lệnh) Sau tự tay viết số chương trình ngắn; chương trình hoàn toàn mới, thay đổi chút từ chương trình phần tài liệu Điều giúp bạn hiểu cách dùng ngôn ngữ cách cụ thể Nếu mục đích bạn sử dụng Python viết đoạn mã ngắn mà không cần sử dụng thư viện Python, Như có lẽ đủ Tuy vậy, phần lớn người đọc cần nghiên cứu thêm với kiểu thức đặc điểm lập trình hướng đối tượng mô-đun/gói chương trình Python Vì bạn nên đọc Phần 12 Đó tảng để bạn sử dụng tốt Python Cuối cùng, bạn nhận thấy nhiều lập trình viên Python sử dụng đặc điểm lập trình theo hàm Python, bạn muốn hiểu chương trình người khác muốn sử dụng đặc điểm Nếu vậy, phần 14 nơi bạn bắt đầu Đừng quên phụ lục! Những phụ lục quan trọng A A.3 File nguồn chương trình download địa http://heather.cs.ucdavis.edu/~matloff/Python/ PythonIntro.tex, dó bạn không cần phải tự tay gõ chương trình Bạn soạn thảo file này, lưu lại dòng lệnh chương trình mà bạn cần, dùng chuột thực copy-paste hướng dẫn có liên quan Nhưng bạn muốn tự tay gõ nội dung chương trình ví dụ cần đảm bảo gõ xác có tài liệu, đặc biệt chỗ thụt đầu dòng Điều quan trọng, sau ta bàn đến Tôi có số tài liệu hướng dẫn lập trình Python theo mục đích cụ thể chẳng hạn: lập trình mạng, kiểu lặp / chuỗi số phát sinh Xem thêm http://heather.cs.ucdavis.edu/~matloff/python html 3.1 Một ví dụ hướng dẫn phút Mã lệnh chương trình ví dụ Dưới đoạn chương trình ngắn, đơn giản Giả sử ta cần tính giá trị hàm x g(x) = − x2 ứng với x = 0.1, 0.2, , 0.9 Để thực điều này, dùng đoạn chương trình sau: for i in range(10): x = 0.1*i print x print x/(1-x*x) lưu vào file, chẳng hạn fme.py, sau chạy chương trình cách gõ lệnh sau dấu nhắc hệ thống (trong Windows, bạn double-click vào tên file) python fme.py Kết cho có dạng sau: 0.0 0.0 0.1 0.10101010101 0.2 0.208333333333 0.3 0.32967032967 0.4 0.47619047619 0.5 0.666666666667 0.6 0.9375 0.7 1.37254901961 0.8 2.22222222222 0.9 4.73684210526 3.2 Kiểu liệu dạng danh sách (list) Chương trình nêu hoạt động nào? Trước hết, hàm range() Python ví dụ list (mảng chiều),3 hình thức không rõ ràng Với Python, list đóng vai trò bản, gặp phải từ “list” tài liệu này, bạn nên hiểu cấu trúc liệu kiểu mảng thay định ngh¨ıa từ vựng Tiếng Anh Hàm range() Python trả lại kết list gồm số nguyên liên tiếp, trường hợp ví dụ nêu l [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Chú ý cách viết thức list Python List gồm chuỗi đối tượng (có thể đủ kiểu không riêng kiểu số, phân cách dấu phẩy cặp ngoặc vuông Như vậy, câu lệnh for ví dụ kể tương tự với: for i in [0,1,2,3,4,5,6,7,8,9]: Chắc bạn đoán được, lệnh thực vòng lặp 10 lần, lần i = 0, sau i = 1, Python có cấu trúc lặp while (cho dù không cóuntil) Ngoài ra, lệnh break giống C/C++ cho phép sớm thoát khỏi vòng lặp Chẳng hạn: >>> x = >>> while 1: x += if x == 8: print x break 3.3 Khối lệnh Python Bây ý đến dấu hai chấm tưởng vô dụng cuối dòng lệnh for, nơi bắt đầu khối lệnh Khác với ngôn ngữ kiểu C/C++ Perl sử dụng cặp ngoặc nhọn để giới hạn khối lệnh, Python sử dụng dấu hai chấm cách viết thụt đầu dòng để làm việc Giờ dùng dấu hai chấm để thông tin đến dịch lệnh Python, Chào dịch lệnh Python, bạn khoẻ chứ? Tôi muốn báo cho bạn biến rằng, cách thêm vào dấu hai chấm này, khối lệnh bắt đầu dòng Tôi thụt đầu dòng hai dòng tiếp theo, để báo cho bạn biến ba dòng hợp thành khối lệnh Trong tài liệu viết thụt dòng khoảng cách chữ (không thiết 3, miễn thống nhất) Chẳng hạn, phải viết4 Ở tạm gọi “mảng”, nhiên sau bạn thấy chúng linh hoạt kiểu liệu tương tự ngôn ngữ C/C++ Ở g() hàm định nghĩa ví dụ for i in range(10): print 0.1*i print g(0.1*i) dịch lệnh Python thông báo lỗi, nói mắc lỗi cú pháp.5 Chúng ta phép thụt cột thêm lần có khối lệnh thuộc khối lệnh khác, chẳng hạn: for i in range(10): if i%2 == 1: print 0.1*i print g(0.1*i) Ở in tương ứng với i số lẻ % toán tử“mod”, giống C/C++.6 Bên cạnh đó, cần ý câu lệnh Python kiểu print a or b or c, biểu thức a (tức khác 0) in b c không; điều thường thấy Python Cũng cần nhắc lại, ý dấu hai chấm cuối lệnh if, hai dòng lệnh print viết thụt cột so với dòng lệnh if Bên cạnh cần ý khác với C/C++/Perl, dấu hai chấm cuối câu lệnh bình thường Python Mỗi dòng câu lệnh Nếu bạn cần viết dòng dài, dùng dấu sổ ngược đây: x = y + \ z 3.4 Python có chế độ gõ lệnh tương tác Một đặc điểm hay Python khả hoạt động với chế độ tương tác (dòng lệnh) Thường bạn không dùng lập trình, cách tiện lợi, nhanh chòng thử mã lệnh để xem hoạt động Khi bạn không tác dụng thứ bạn nói “Phải thử xem sao!”, chế độ tương tác dòng lệnh cho phép làm việc nhanh chóng, dễ dàng Trong tài liệu này, sử dụng kiểu tương tác dòng lệnh cách minh hoạ nhanh chóng cho đặc điểm Python Thay chạy chương trình từ dấu nhắc hệ thống (batch mode - chạy toàn chương trình lần), ta gõ lệnh để máy thực chế độ tương tác: % python >>> for i in range(10): x = 0.1*i print x print x/(1-x*x) Hãy ghi nhớ: Những người bắt đầu sử dụng Python thường bị mắc lỗi kiểu Hầu hết toán tử thường dùng C có Python, kể toán tử so sánh (==) bạn thấy Còn kí hiệu 0x dành cho hệ số 16, giống FORTRAN, kí hiệu ** dành cho hàm mũ Bên cạnh lệnh ifcó thể kèm theo else thông thường, bạn viết gọn else if thành elif Các toán tử Boolean gồm có and, or not 0.0 0.0 0.1 0.10101010101 0.2 0.208333333333 0.3 0.32967032967 0.4 0.47619047619 0.5 0.666666666667 0.6 0.9375 0.7 1.37254901961 0.8 2.22222222222 0.9 4.73684210526 >>> Ở khởi động Python, dấu nhắc tương tác >>> xuất Sau việc gõ lệnh vào, dòng Bất lúc khối lệnh dấu nhắc có dạng đặc biệt, “ ” Và gõ dòng trống cuối mã lệnh máy hiểu nhập xong dòng lệnh bắt đầu chạy.7 Trong chế độ tương tác lệnh, bạn tìm câu lệnh gõ vào lần trước phím mũi tên lên xuống, không cần gõ lại Để thoát khỏi chế độ dòng lệnh, ấn Ctrl-D (Ctrl-Z Windows) In tự động: Trong chế độ tương tác dòng lệnh, ta tham chiếu tạo đối tượng, biểu thức mà chưa cần gán tên biến cho giá trị biểu thức in (không cần gõ lệnh print) Chẳng hạn: >>> for i in range(4): 3*i Chế độ tương tác lệnh cho phép thực dòng lệnh Python tính toán giá trị biểu thức đơn lẻ Ở đây, gõ vào thực lệnh lặp for Chế độ tương tác lệnh không cho phép gõ vào chương trình Về mặt kĩ thuật, thực ta thực điều cách bắt đầu dòng lệnh kiểu “if 1:”, đưa chương trình vào câu lệnh if lớn, dù cách thuận tiện để gõ nội dung chương trình lớn Với Pythonwin Ctrl+mũi tên Chú ý l tham biến cho checkline() Dĩ nhiên đoạn mã rút ngắn thêm, với phần trung tâm chương trình nói đổi thành: map(checkline,open(sys.argv[1]).readlines) Nhưng điều dẫn đến việc đọc gỡ rối chương trình khó khăn 14.3 Lọc Hàm filter() hoạt động giống map(), khác lấy phần tử dãy thỏa mãn điều kiện định Hàm áp dụng filter() phải trả giá trị boolean (true false) Chẳng hạn: >>> >>> >>> [5, x = [5,12,-2,13] y = filter(lambda z: z > 0, x) y 12, 13] Một lần nữa, điều cho phép ta tránh viết vòng for lệnh if 14.4 List Comprehension Điều cho phép ta rút ngắn vòng lặp for mà cho kết danh sách Lấy ví dụ: >>> x = [(1,-1), (12,5), (8,16)] >>> y = [(v,u) for (u,v) in x] >>> y [(-1, 1), (5, 12), (16, 8)] Viết gọn so với gán [] cho y, sau vòng lặp for mà ta gọi y.append() 14.5 Chiết giảm Hàm reduce() sử dụng để thực cộng dồn phép toán số học kiểu toàn danh sách Chẳng hạn, >>> x = reduce(lambda x,y: x+y, range(5)) >>> x 10 Ở range(5) dĩ nhiên [0,1,2,3,4] Trước hết, hàm reduce() cộng hai phần tử [0,1,2,3,4], tức đóng vai trò x đóng vai trò y Tổng chúng Sau tổng đó, 1, lại đóng vai trò 42 x phần tử [0,1,2,3,4], tức 2, đóng vai trò y, chúng cho ta kết 3, Cuối reduce() hoàn thành xong nhiệm vụ trả lại kết 10 Một lần nữa, điều cho phép ta tránh vòng lặp for, với câu lệnh khởi tạo x trước vòng for 15 Các biểu thức phát sinh Gợi nhớ lại lợi lớn thể lặp ta thường xuyên sử dụng chúng mà không tạo danh sách lớn nhớ Các biểu thức phát sinh giới thiệu Python 2.4, cho ta cải tiến tương tự list comprehension Xét ví dụ ngắn sau đây, ta ôn lại list comprehension giới thiệu biểu thức phát sinh >>> x = [1,2,4,12,5] >>> [i for i in x] [1, 2, 4, 12, 5] >>> [i for i in x if i > 4] [12, 5] >>> sum(i for i in x if i > 4) 17 >>> min(i for i in x if i > 4) Nói cách khác, biểu thức phát sinh có dạng list comprehension, khác hai điểm sau: • biểu thức nằm cặp ngoặc tròn thay ngoặc vuông • hàm áp dụng cho thể lặp áp dụng cho biểu thức34 Tiện thể cần nói, hàm min() sử dụng với tham biến thông thường: >>> min(5,12,3) >>> y = [5,12,4] >>> min(y) Hơn nữa, sử dụng thứ so sánh theo thứ tự trước-sau: >>> min(’def’,’cxyg’) ’cxyg’ >>> min([4,’abc’],[8,5],[3,200]) [3, 200] Dĩ nhiên max() tương tự Nếu ta kết hợp chúng lại biểu thức phát sinh có lợi 34 Chú ý cặp ngoặc tròn xung quanh biểu thức đóng vai trò ngoặc cho hàm 43 A Gỡ lỗi Bạn đừng nên gỡ lỗi cách thêm dòng lệnh print vào chương trình Thay vào đó, sử dụng công cụ gỡ lỗi Nếu bạn không thường xuyên sử dụng công cụ phải lập trình khó khăn tốn nhiều thời gian Xem trình bày địa http://heather.cs.ucdavis.edu/ ~matloff/debug.html A.1 Công cụ gỡ lỗi sẵn có Python, PDB Bộ gỡ lỗi sẵn có Python, PDB, tương đối sơ khai, nêu theo tăng dần mức độ hữu dụng: • Dạng • Dạng tăng cường sử dụng thêm macro có chiến lược • Dạng kết hợp với gỡ lỗi đồ họa DDD A.1.1 Dạng Bạn tìm thấy PDB thư mục lib hệ thống file Python Chẳng hạn, hệ điều hành Unix, chỗ /usr/lib/python2.2, /usr/local/lib/python2.4,v.v Để gỡ lỗi script x.py, gõ lệnh: % /usr/lib/python2.2/pdb.py x.py (Nếu x.py có tham số dòng lệnh, chúng phải đặt sau tên x.py dòng lệnh.) Dĩ nhiên bạn sử dụng PDB nhiều, tốt đặt cho bí danh (ví dụ Unix): alias pdb /usr/lib/python2.2/pdb.py bạn cần viết cách đơn giản % pdb x.py Một bạn PDB, đặt điểm dừng đầu tiên, chẳng hạn dòng 12: b 12 Ấn c (“continue”), cách bạn vào file x.py dừng lại chỗ có điểm dừng Sau tiếp tục bình thường, với thao tác tương tự GDB:35 35 Trong số trường hợp, lệnh không hoạt động tận bạn thực vào bên mã nguồn cần gỡ lỗi Chẳng hạn, gõ l (“list” dòng) sớm gây thông báo lỗi 44 • b (“break”) : đặt điểm dừng • tbreak : đặt điểm-dừng-một-lần • l (“list”) : liệt kê số dòng mã nguồn • n (“next”) : nhảy đến dòng tiếp theo, bỏ qua mã lệnh dòng • s (“subroutine”) : nhảy đến dòng có duyệt qua lệnh hàm • c (“continue”) : tiếp tục thực tận gặp điểm dừng • w (“where”) : nhận báo cáo tình trạng stack • u (“up”) : di chuyển lên mức stack, chẳng hạn để truy vấn biến địa phương • d (“down”) : di chuyển xuống mức stack • j (“jump”) : nhảy đến dòng khác mà không can thiệp đến mã lệnh thực • h (“help”) : xem hướng dẫn trực tuyến (ngắn gọn) (chẳng hạn h b để xem hướng dẫn câu lệnh b Đơn giản hơn, gõ h để xem danh sách toàn lệnh • q (“quit”) : thoát khỏi PDB Bạn nên dùng lệnh help pdb lần Nó cho biết toàn thông tin tính khác PDB Khi vào PDB, dấu nhắc (Pdb) xuất Nếu bạn có chương trình gồm nhiêu file, điểm dừng có dạng module_tên:số_TT_dòng Chẳng hạn, bạn có chương trình x.py, nhập file y.py Bạn thiết lập điểm dừng dòng thứ file y.py sau: (Pdb) b y:8 Dù vậy, cần ý điều thực y thực nhập từ x Chú ý chạy PDB, bạn đồng thời chạy Python chế độ tương tác dòng lệnh Do đó, bạn gõ dòng lệnh Python dấu nhắc PDB Bạn đặt biến, gọi hàm, v.v Điều có lợi vài trường hợp sau Chẳng hạn, dù PDB có lệnh p nhằm in giá trị biến biểu thức, thường không cần thiết Vì sao? Trong chế độ tương tác lệnh Python ta cần gõ tên biến hay biểu thức kết hiển thị hình—giống hệt lệnh p làm Như vậy, ta không cần phải gõ ‘p’ Vậy x.py bao gồm biến ww chạy PDB; thay gõ (Pdb) p ww bạn cần gõ 45 ww giá trị ww in hình.36 Nếu bạn có chương trình với cấu trúc liệu phức tạp, bạn viết hàm để in hình toàn phần khác cấu trúc Sau này, PDB cho phép bạn thực câu lệnh Python từ dấu nhắc PDB, bạn đơn giản gọi hàm từ dấu nhắc, từ in cách cụ thể ứng dụng Sau chương trình bạn kết thúc PDB hay lỗi thực hiện, bạn chạy lại mà không cần thoát khỏi PDB–điều quan trọng bạn không muốn điểm dừng–bởi việc ấn c Chú ý bạn thường xuyên (dù luôn) bắt buộc chương trình phải kết thúc, thông qua lệnh j, nhảy đến câu lệnh cuối chương trình, sau ấn c Hơn nữa, tiếp sau bạn sửa đổi mã lệnh sửa đổi phản ánh PDB.37 A.1.2 Lưu ý lệnh Next Step Nếu bạn lệnh cho PDB thực Step đơn kiểu n dừng dòng lệnh Python có nhiều thao tác, bạn cần phải lặp lại lệnh n nhiều lần (hoặc thiết lập điểm dừng tạm thời để nhảy qua dòng đó) Thí dụ, for i in range(10): thực hai nhiệm vụ Thứ gọi hàm range(), sau đặt biến i, bạn cần phải lệnh n hai lần Thế lệnh sao? y = [(y,x) for (x,y) in x] Nếu chẳng hạn x có 10 phần tử bạn phải thực lệnh n 10 lần! Ở chắn bạn muốn thiết lập điểm dừng tạm thời để giải vấn đề A.1.3 Sử dụng Macro PDB Rõ ràng đặc tính đơn giản PDB khắc phục phần cách tận dụng lệnh alias Cá nhân khuyến khích dùng lệnh Chẳng hạn, bạn gõ alias c c;;l 36 Tuy vậy, tên biến lại trùng với lệnh PDB (hoặc từ viết tắt nó), lệnh thực Thí dụ, bạn có biến n, việc gõ n cho kết thực lệnh n[ext] thay in giá trị n Để in dược giá trị này, bạn phải gõ p n 37 PDB, thấy, chương trình Python Khi bạn khởi động lại, nhập lại mã nguồn bạn Bên cạnh đó, lí điểm dừng bạn lưu lại chúng biến PDB Cụ thể hơn, chúng lưu biến thàn viên có tên breaks lớp Pdb thuộc pdb.py Biến thiết lập từ điển, với khóa tên file nguồn py, mục danh sách điểm dừng 46 Bằng cách này, đỗ lại điểm dừng, bạn tự động thấy đoạn mã Đặc điểm khắc phục nhiều cho khiếm khuyết mặt giao diện đồ họa PDB Điều thực tế quan trọng bạn nên đặt file khởi động PDB, Unix có tên $HOME/.pdbrc.38 Bằng cách alias có hiệu nghiệm Bạn làm tương tự lệnh n s: alias c c;;l alias n n;;l alias s s;;l Trong PDB có lệnh unalias Bạn viết macro khác dành riêng cho chương trình gỡ lỗi Chẳng hạn, lần giả dụ bạn có biến tên ww x.py, bạn muốn kiểm tra giá trị lần chương trình gỡ lỗi tạm dừng, điểm dừng chẳng hạn Muốn ta thay đổi bí danh (alias) thành: alias c c;;l;;ww Bạn viết bí danh cho lệnh Python nào, bao gổm tham số Chẳng hạn mã nguồn bạn có lớp C, biến thành viên V Giả sử có danh sách L bao gồm đối tượng lớp C Như ta có bí danh kiểu như: (Pdb) alias pl for I in L: print I.V Để định nghĩa bí danh, ta có tham số, tham chiếu đến bởi: %1, (%2 v.v Hoặc, bạn định nghĩa hàm nhằm mục đích gỡ lỗi chương trình nguồn, chẳng hạn Dbg(), sau tạo bí danh để lần sau đỡ phải gõ: alias dbg Dbg() A.1.4 Sử dụng dict Trong phần A.2.8 đây, ta cho thấy c đối tượng thuộc lớp đó, gõ o. dict in toàn biến thành viên đối tượng Bạn kết hợp đặc điểm với chức đặt bí danh PDB, chẳng hạn: alias c c;;l;;o dict A.2 Sử dụng PDB với DDD DDD, có sẵn nhiều hệ thống Unix (và download tự hệ thống bạn chưa có nó), giao diện đồ họa cho nhiều chương trình gỡ lỗi, chẳng hạn GDB (cho C/C++), JDB (cho Java), trình gỡ lỗi có sẵn Perl, v.v Nó dùng cho PDB Python, giúp ta nâng cao hiệu làm việc 38 Python kiểm tra tồn file thư mục thời 47 A.2.1 Chuẩn bị Ứng dụng DDD cho PDB Richard Wolff thực Ông chỉnh sửa file pdb.py nhằm mục đích này, tạo thành file PDB có tên pydb.py Ban đầu dành cho Python 1.5, nhiên sau Richard cung cấp cập nhật quý báu bao gồm file sau đây: http://heather.cs.ucdavis.edu/~matloff/Python/DDD/pydb.py http://heather.cs.ucdavis.edu/~matloff/Python/DDD/pydbcmd.py http://heather.cs.ucdavis.edu/~matloff/Python/DDD/pydbsupt.py Đặt hai file vào chỗ thư mục tìm kiếm bạn, chẳng hạn /usr/bin Đảm bảo bạn cho chúng quyền thực A.2.2 Khởi động DDD mở chương trình Để bắt đầu, chẳng hạn gỡ lỗi file fme2.py Phần 6.2.4, trước hết đảm bảo main() thiết lập trình bày phần Khi bạn kích hoạt DDD, bảo sử dụng PYDB: ddd debugger /usr/bin/pydb.py Sau cửa sổ dòng lệnh DDD, tức cửa sổ dòng lệnh PDB (gần phía cùng), gõ: (pdb) file fme2.py chon File | Open Source click đúp chuột vào tên file Sau này, cần sửa đổi mã nguồn, bạn gõ lệnh (pdb) file fme2.py Hoặc chọn File | Open Source hay File | Open Recent click đúp vào tên file Các điểm dừng lần chạy cuối giữ nguyên A.2.3 Các điểm dừng Khi đặt điểm dừng, click phải chuột vào khoảng trống dòng mã nguồn bạn chọn Set Breakpoint (hoặc Set Temporary Breakpoint (đặt điểm dừng tạm thời) Continue to Until Here (tiếp tục đến tận đây), trường hợp) 48 A.2.4 Chạy chương trình nguồn bạn Để chạy, chọn Program | Run, điền thông số chương trình bạn (nếu có) vào hộp “Run with Argument”, click Run cửa sổ Bạn đề nghị ấn tiếp Continue, mà bạn làm cách ấn Program | Run |, tiện lợi click vào Continue cửa sổ nhỏ có nhiệm vụ tóm tắt dòng lệnh (Tuy đừng sử dụng lệnh Run đó) Sau bạn click Next, Step, Cont v.v Dấu trỏ đến dòng lệnh thực có hình chữ ‘I’, mờ trỏ chuột không nằm phạm vi mã nguồn cửa sổ DDD Cũng cần nói thêm, bạn đừng gọi sys.argv đoạn mã lệnh đứng tự lớp Khi chương trình bạn lần đầu nạp, đoạn mã lệnh đứng tự lớp thực Nhưng tham số dòng lệnh chưa nạp nên kết có lỗi “index out of range” (thứ tự vượt khoảng cho phép) Hãy tránh điều đưa mã lệnh có chứa sys.argv vào hàm lớp, hẳn phía lớp A.2.5 Theo dõi biến Bạn xem giá trị biến cách di trỏ chuột tới chỗ có tên biến cửa sổ mã nguồn Như đề cập đến Phần A.1.4, o đối tượng lớp đó, việc gõ o. dict in toàn biến thành viên lớp Trong DDD, bạn làm điều dễ dàng sau Đơn giản đặt biểu thức sau dấu thích: # o dict sau muốn xem xét giá trị biến thành viên o, đưa trỏ chuột đến biểu thức dấu thích! Tận dụng đặc điểm DDD, ta cho hiển thị biến cách liên tục Đơn giản click phải chuột lên chỗ có biến đó, sau chọn Display A.2.6 Các vấn đề hỗn hợp Được phát triển với ý định ban đầu dành cho C/C++, DDD phù hợp với Python Nhưng DDD chuyển đổi lệnh mà bạn click thành lệnh cho PDB, bạn thấy cửa sổ dòng lệnh DDD; nên việc bạn thực với DDD, bạn gõ lệnh PDB vào cửa sổ dòng lệnh Cũng cần nói thêm PYDB, phiên sửa đổi PDB dùng DDD, lệnh alias A.2.7 Một số hỗ trợ gỡ lỗi có sẵn Python Có số hàm có sẵn Python mà bạn thấy hữu dụng trình gỡ lỗi 49 A.2.8 Thuộc tính dict Hãy nhớ lại thực thể lớp vận hành từ điển Nếu có thực thể lớp tên i, bạn xem từ điển thông qua i. dict Nó cho thấy giá trị toàn biến thành viên lớp A.2.9 Hàm id() Đôi lúc bạn cần biết địa thực tế đối tượng nhớ Chẳng hạn, có hai biến mà bạn nghĩ chúng đến đối tượng, không chắn Phương thức id() cho bạn địa đối tượng Chẳng hạn: >>> x = [1,2,3] >>> id(x) -1084935956 >>> id(x[1]) 137809316 (Đừng băn khoăn địa âm, thực tế địa có số lớn coi số nguyên bù (two’s complement)) A.2.10 Các công cụ / IDE gỡ lỗi khác Bộ gỡ lỗi Winpdb The new Winpdb debugger(www.digitalpeers.com/pythondebugger/),39 có vẽ tốt Đặc biệt dựa gỡ lỗi cũ có tên RPDB vốn xử lí thread Python tốt Tuy vậy, tài liệu Winpdb, đến tận tháng năm 2006 sơ sài, chưa có dịp để dùng Hãy tìm cập nhật (nếu có), http://heather.cs.ucdavis.edu/ ~matloff/rpdb.html Cá nhân không thích môi trường phát triển tích hợp (IDE) Chúng thường tải chậm thường không cho dùng chương trình soạn thảo văn ưa thích,40 theo quan điểm IDE chức Tuy vậy, bạn thích IDE sau số gợi ý: Bạn muốn thử IDLE, công cụ IDE kèm sẵn với gói Python, thấy có nhiều khiếm khuyết Nhưng nghe ý kiến tốt IDE miễn phí sau: Boa Constructor, http:// boa-constructor.sourceforge.net/; Eclipse với phần mở rộng Python, http://www.python org/moin/EclipsePythonIntegration; JEdit, http://www.jedit.org/ Tôi có viết hướng dẫn Eclipse http://heather.cs.ucdavis.edu/~matloff/eclipse.html Còn số phần mềm thương mại, ưa chuộng Wing Edit, http://wingware.com/ wingide/platforms, công cụ mà sử dụng thời gian ngắn cho Java 39 Không tên gọi nó, công cụ không dành riêng cho máy chạy Microsoft Windows Tôi dùng vim, điều muốn dùng chương trình soạn thảo cho tất việc—lập trình, soạn thảo, e-mail, phát triển trang Web, v.v 40 50 A.3 A.3.1 Tài liệu trực tuyến Hàm dir() dir() hàm tiện dụng cho phép ta xem nhanh thành phần có đối tượng hàm Bạn nên sử dụng thường xuyên Để minh họa, ví dụ Phần 7, chẳng hạn dừng lại dòng: print "Số file văn mở là: ", textfile.ntfiles Sau muốn kiểm tra số điều với hàm dir(), chẳng hạn: (Pdb) dir() [’a’, ’b’] (Pdb) dir(textfile) [’ doc ’, ’ init ’, ’ module ’, ’grep’, ’wordcount’, ’ntfiles’] Ngay sau bạn khởi động Python, có nhiều thứ tải Chúng ta xem: >>> dir() [’ builtins ’, ’ doc ’, ’ name ’] >>> dir( builtins ) [’ArithmeticError’, ’AssertionError’, ’AttributeError’, ’DeprecationWarning’, ’EOFError’, ’Ellipsis’, ’EnvironmentError’, ’Exception’, ’False’, ’FloatingPointError’, ’FutureWarning’, ’IOError’, ’ImportError’, ’IndentationError’, ’IndexError’, ’KeyError’, ’KeyboardInterrupt’, ’LookupError’, ’MemoryError’, ’NameError’, ’None’, ’NotImplemented’, ’NotImplementedError’, ’OSError’, ’OverflowError’, ’OverflowWarning’, ’PendingDeprecationWarning’, ’ReferenceError’, ’RuntimeError’, ’RuntimeWarning’, ’StandardError’, ’StopIteration’, ’SyntaxError’, ’SyntaxWarning’, ’SystemError’, ’SystemExit’, ’TabError’, ’True’, ’TypeError’, ’UnboundLocalError’, ’UnicodeDecodeError’, ’UnicodeEncodeError’, ’UnicodeError’, ’UnicodeTranslateError’, ’UserWarning’, ’ValueError’, ’Warning’, ’ZeroDivisionError’, ’_’, ’ debug ’, ’ doc ’, ’ import ’, ’ name ’, ’abs’, ’apply’, ’basestring’, ’bool’, ’buffer’, ’callable’, ’chr’, ’classmethod’, ’cmp’, ’coerce’, ’compile’, ’complex’, ’copyright’, ’credits’, ’delattr’, ’dict’, ’dir’, ’divmod’, ’enumerate’, ’eval’, ’execfile’, ’exit’, ’file’, ’filter’, ’float’, ’frozenset’, ’getattr’, ’globals’, ’hasattr’, ’hash’, ’help’, ’hex’, ’id’, ’input’, ’int’, ’intern’, ’isinstance’, ’issubclass’, ’iter’, ’len’, ’license’, ’list’, ’locals’, ’long’, ’map’, ’max’, ’min’, ’object’, ’oct’, ’open’, ’ord’, ’pow’, ’property’, ’quit’, ’range’, ’raw_input’, ’reduce’, ’reload’, ’repr’, ’reversed’, ’round’, ’set’, ’setattr’, ’slice’, ’sorted’, ’staticmethod’, ’str’, ’sum’, ’super’, ’tuple’, ’type’, ’unichr’, ’unicode’, ’vars’, ’xrange’, ’zip’] 51 Vậy đó, có danh sách tất hàm có sẵn thuộc tính khác mà bạn thấy! Nếu bạn muốn biết hàm thuộc tính khác có kiểu từ điển: >>> dir(dict) [’ class ’, ’ cmp ’, ’ contains ’, ’ delattr ’, ’ delitem ’, ’ doc ’, ’ eq ’, ’ ge ’, ’ getattribute ’, ’ getitem ’, ’ gt ’, ’ hash ’, ’ init ’, ’ iter ’, ’ le ’, ’ len ’, ’ lt ’, ’ ne ’, ’ new ’, ’ reduce ’, ’ reduce_ex ’, ’ repr ’, ’ setattr ’, ’ setitem ’, ’ str ’, ’clear’, ’copy’, ’fromkeys’, ’get’, ’has_key’, ’items’, ’iteritems’, ’iterkeys’, ’itervalues’, ’keys’, ’pop’, ’popitem’, ’setdefault’, ’update’, ’values’] Giả dụ muốn tìm xem phương thức thuộc tính gắn với kiểu chuỗi Như bạn biết qua phần 6.2.2, chuỗi trở thành lớp có sẵn Python, ta gõ: >>> dir(string) Mà thay vào phải dùng đối tượng chuỗi bất kì: >>> dir(’’) [’ add ’, ’ class ’, ’ contains ’, ’ delattr ’, ’ doc ’, ’ eq ’, ’ ge ’, ’ getattribute ’, ’ getitem ’, ’ getnewargs ’, ’ getslice ’, ’ gt ’, ’ hash ’, ’ init ’, ’ le ’, ’ len ’, ’ lt ’, ’ mod ’, ’ mul ’, ’ ne ’, ’ new ’, ’ reduce ’, ’ reduce_ex ’, ’ repr ’, ’ rmod ’, ’ rmul ’, ’ setattr ’, ’ str ’, ’capitalize’, ’center’, ’count’, ’decode’, ’encode’, ’endswith’, ’expandtabs’, ’find’, ’index’, ’isalnum’, ’isalpha’, ’isdigit’, ’islower’, ’isspace’, ’istitle’, ’isupper’, ’join’, ’ljust’, ’lower’, ’lstrip’, ’replace’, ’rfind’, ’rindex’, ’rjust’, ’rsplit’, ’rstrip’, ’split’, ’splitlines’, ’startswith’, ’strip’, ’swapcase’, ’title’, ’translate’, ’upper’, ’zfill’] A.3.2 Hàm help() Chẳng hạn, tìm hiểu phương thức pop() danh sách: >>> help(list.pop) Help on method_descriptor: pop( ) L.pop([index]) -> item remove and return item at index (default last) (END) 52 phương thức center() chuỗi: >>> help(’’.center) Help on function center: center(s, width) center(s, width) -> string Return a center version of s, in a field of the specified width padded with spaces as needed The string is never truncated Ấn ’q’ để thoát khỏi trang hướng dẫn Bạn lấy thông tin cách sử dụng pydoc dấu nhắc lệnh Unix, chẳng hạn: % pydoc string.center [ trên] A.4 Giải thích biện pháp xử lí biến lớp cũ Trước Python phiên 2.2, hỗ trợ dành cho phương thức lớp Nhưng có biện pháp xử lí đơn giản trình bày http://aspn.activestate.com/ASPN/Cookbook/ Python/Recipe/52304 Bây Python cho phép phương thức lớp (thực tế hai loại), không cần biện pháp xử lí lập trình, ví dụ hay cho ta thấy nguyên tắc hoạt động tham chiếu đối tượng Chúng ta tìm hiểu điều này: Trong chương trình tfe.py phần 7, thêm class ClassMethod: def init (self,MethodName): self. call = MethodName class textfile: (lots of stuff omitted) def printntfiles(): print textfile.ntfiles tmp = ClassMethod(printntfiles) printntfiles = tmp textfile.printntfiles() (Tôi thêm vào dòng—dòng với phép gán cho tmp—để rõ ràng hơn, bạn thấy sau này.) Nhớ lại phần 8, hàm Python (con trỏ đến) đối tượng, giống thứ khác, gán Chẳng hạn, đoạn mã đây: 53 >>> def f(x): return x*x >>> g = f >>> g(3) f thực chất trỏ đến “đối tượng hàm”, ta gán f cho g, g đến đối tượng đó, g hàm tính Mặt khác, cần lưu ý thực thể lớp gọi Đó phương thức call (), phần ngầm định tất lớp Do đơn giản vờ thực thể lớp hàm, sau gọi Khi đó, phương thức call () kích hoạt self (nghĩa thực thể lớp mà “gọi”) với tham số nhập vào Phương thức call () mặc định rỗng, cho thông số sử dụng theo mục đích riêng Thí dụ, file nguồn sau có tên yyy.py: class u: def init (self): self.r = def call (self,z): return self.r*z def main(): a = u() print a(5) a.r = 13 print a(5) if name == ’ main ’: main() python yyy.py 40 65 Bây xem dòng lệnh sau file nguồn áp dụng biện pháp xử lí: tmp = ClassMethod(printntfiles) Nó có tác dụng tạo thực thể lớp ClassMethod gán cho tmp Tham số printntfiles, dòng lệnh kiến tạo: self. call = MethodName 54 có nghĩa tmp. call đặt cho printntfiles Hãy tạm quên tmp. call printntfiles hàm; ý gán trỏ (printntfiles) cho (tmp. call ) Tuy hai dĩ nhiên hàm, tmp. call alf trỏ tới mã hàm ban đầu printntfiles, tức tới mã: print textfile.ntfiles Và dòng printntfiles = tmp có nghĩa biến printntfiles không đến mã lệnh nữa! Thay vào đó, đến thực thể lớp ClassMethod Hãy nhớ rằng, printntfiles thân biến lớp lớp textfile, nghĩa có tên đầy đủ textfile.printntfiles Ban đầu hàm, thứ gán được, nên đơn giản biến, đến thực thể lớp ClassMethod Điều cần nói ta gọi textfile.printntfiles—mà ta thực được, lớp Python “gọi được”!—thì ta kích hoạt phương thức call () thực thể Và phương thức này, thấy trên, đến mã nguồn gốc ban đầu hàm printntfiles, nghĩa là: print textfile.ntfiles Do mà đoạn mã thực hiện! Tòm lại lệnh có cú pháp lời gọi phương thức lớp, textfile.printntfiles() thực tế đóng vai trò phương thức lớp, Python hình thức A.5 Đưa tất biến toàn cục vào lớp Như nói phần 5, thay sử dụng từ khóa global, làm rõ ràng có tổ chức cách nhóm tất biến toàn cục vào lớp Ở đây, file tmeg.py, ta làm vậy, cải tiến so với file tme.py: # đọc vào file text có tên định dòng lệnh, # thông báo số dòng số từ có file import sys def checkline(): glb.linecount += 55 w = glb.l.split() glb.wordcount += len(w) class glb: linecount = wordcount = l = [] f = open(sys.argv[1]) for glb.l in f.readlines(): checkline() print glb.linecount, glb.wordcount Chú ý chương trình chạy lần đầu, lớp glb thực hiện, chí trước khởi động main() 56 ... tác giả, ưa chuộng Python ngôn ngữ rõ ràng tinh tế Đối với người phát triển hệ thống Google Python ngôn ngữ quen thuộc Những người ủng hộ Python, thường gọi Pythonista, cho ngôn ngữ sáng tiện dụng... phép tính cấp cao xây dựng sẵn ngôn ngữ, chẳng hạn kết nối chuỗi kí tự push/pop stack • thông dịch thay biên dịch thành ngôn ngữ máy 1.2 Tại nên dùng Python? Ngày ngôn ngữ kịch phổ biến có lẽ Perl... không tĩnh (non-static) Thuật ngữ biến thực thể thuật ngữ chung lập trình hướng đối tượng, riêng cho ngôn ngữ 23 Để thấy chúng hoạt động Python, trước hết nhớ lại biến Python hình thành ta gán cho