Hướng dẫn dùng 12 elements python
Bài viết được sự cho phép của tác giả Nguyễn Việt Hưng Show Nội dung chính
Một câu hỏi nhạt toẹt của nhà phỏng vấn có thể đưa ra (với người phỏng vấn thường có kiến thức từ ngôn ngữ khác như Java, PHP hay C++, hoặc một chuyên gia Python thực sự và hỏi để check xem bạn có mắc bẫy không – loại này thì hiếm, và không rảnh 🙄). Tuyển python nhiều vị trí lương cao Python dùng call-by-value hay call-by-reference?Hai khái niệm này thực ra không tồn tại trong Python, bạn có thể đào tung cả trang document của Python cũng sẽ không thấy nói gì về khái niệm này. Tức là: nó không có thật! Nó không cần thiết! bạn chỉ cần hiểu function hoạt động thế nào, cách Python sử dụng “name binding”. Còn không nên ngồi cãi nhau về “call-by-reference”, “call-by-value” làm gì cho tốn thời gian, vô tác dụng.
Call by XYZ là cái gì?Mọi khái niệm viết sau đây không tồn tại trong Python, các thuật ngữ được viết với “từ vựng” của ngôn ngữ lập trình khác. Trong một số ngôn ngữ như C, C++, khi gọi function ta có truyền vào các “tham số” (pass argument), nếu function đó nhận vào một array (trong Python hiểu nôm na là list), thì trong function, ta sẽ xử lý chính array đó hay một bản copy của nó? Kiểu 1 Kiểu 2 Với câu gọi function (call function) thứ nhất ta gọi function với giá trị (value) của biến Câu gọi function thứ hai ta gọi function với con trỏ (pointer) đến biến Những ngôn ngữ lập trình bị ảnh hưởng bởi C thường cắt giảm khái niệm “pointer” để tránh gây phức tạp, vì vậy khi gọi function sẽ mặc định dùng 1 trong 2 kiểu trên. Hoặc dùng một cơ chế khác hoàn toàn. Ví dụ:
Call by và pass by
Chỉ là hai cách tập trung khác nhau vào một việc: call function với các argument. Call function trong Python hoạt động thế nào?Nếu bắt phải đưa ra một từ khoá, thì đó là các argument sẽ được “pass by assignment”. Để thực sự hiểu Python assignment làm gì, bạn cần hiểu về khái niệm name và binding trong Python. Cách hoạt động của name và bindingx = 4 y = x x = x + 1 print(x, y)
Code này đọc theo thuật ngữ của Python như sau:
Vậy rõ ràng kết quả ở đây: Xem ví dụ sau tương tự, nhưng khác hẳn: L = [1,2,3] K = L L[0] = 9 print(L, K)
Đây nhẽ ra, phải là câu hỏi phỏng vấn mặc định cho lập trình viên Python chứ không phải mấy câu vớ vẩn như tiêu đề bài này. Vì sao? vì nếu lập trình viên trả lời đúng, tức là anh ta hiểu cách Python hoạt động, và sẽ không tạo ra những bug rất cơ bản trong chương trình. Hãy đọc đoạn code này theo thuật ngữ Python:
Hãy nhớ >>> L = [1,2,3] >>> K = L >>> L[0] = 9 >>> print(L, K) [9, 2, 3] [9, 2, 3] >>> id(L) 4326049992 >>> id(K) 4326049992 >>> L is K True
Cơ chế hoạt động của function>>> def change(numb, ns): ... numb = numb + 1 ... ns[0] = 0 ... return None ... >>> N = 9 >>> L = [1,2,3] >>> change(N, L) >>> print(N, L) 9 [0, 2, 3] Cơ chế gọi function của Python hoạt động như sau:
Vậy làm sao để không thay đổi list L và thu về một list mới sau khi gọi function? Hãy tạo một bản copy của list rồi dùng bản copy đó. >>> def change(L): ... L = L[:] # slicing là một cách đơn giản để tạo một bản shallow copy ... L[0] = 0 ... return L ... >>> newL = change(L) >>> print(L) [1, 2, 3] >>> print(newL) [0, 2, 3] CHÚ Ý: Nếu list L chứa các mutable object (xem ở
dưới), cần sử dụng function Một số kiểu dữ liệu trong Python không cho phép thay đổi giá trị của nó sau khi tạo ra (immutable) như int, float, str, NoneType, bool, tuple. Vì vậy mỗi lần “thay đổi”, ta sẽ tạo ra một object mới chứa giá trị mới: >>> N = 9 >>> id(N) 4297624192 >>> N = N + 2 >>> id(N) 4297624256 >>> N 11 >>> T1 = (1,2,3) >>> id(T1) 4326100280 >>> T1 = T1 + (3,4,5) >>> id(T1) 4325883048 >>> print(T1) (1, 2, 3, 3, 4, 5) Các kiểu dữ liệu khác cho phép thay đổi sau khi tạo ra (mutable): list, dict, set. >>> L = [1,2,3] >>> id(L) 4326050504 >>> L.extend([3,4,5]) >>> id(L) 4326050504 >>> print(L) [1, 2, 3, 3, 4, 5] Với kiểu mutable, cần đặc biệt chú ý phép toán nào trả về object mới, phép toán nào thay đổi object hiện tại: >>> L = [1,2,3] >>> id(L) 4326050568 >>> L = L + [3,4,5] >>> id(L) 4326095240 >>> L [1, 2, 3, 3, 4, 5]
Python dùng pass by assignment, call by object referencePass by assignment là khái niệm lấy từ Python FAQ, khi mà người ta bắt buộc phải giải thích khái niệm này cho những người đã biết ngôn ngữ lập trình khác. Các name trong function sẽ bind tới các object mà argument đang bind tới. Trong tutorial Python, có viết “các argument được pass sử dụng call by value, với các value luôn luôn là các object reference chứ không phải value của object.” – yup, I lied 😒 Định nghĩa name trong Python:
Liệu bạn có thể bịa ra một thuật ngữ nữa là “call by name” ??!!! Chốt, thôngĐể khỏi đau đầu về những điều này, chỉ cần nắm chắc các khái niệm Trên internet có nhiều nơi hỏi đáp, cố đưa ra một cái tên, nhưng những cái tên đó không có trong tài liệu chính thống của Python. Tham khảo
Bài viết gốc được đăng tải tại pymi.vn Có thể bạn quan tâm:
Xem thêm Việc làm it online hấp dẫn trên TopDev |