10 điều lập trình viên Python nên biết - Phần 3 (cuối)



  • 10 điều lập trình viên Python nên biết - Phần 1
    10 điều lập trình viên Python nên biết - Phần 2

    7. Các cấu trúc sao chép (và cơ bản về quản lý bộ nhớ)

    Hãy nhìn đoạn code sau:

    >>> list1 = [1,2,3,4,5]  
    >>> list2 = list1  
    >>> list2.append(6)  
    >>> list2  
    [1, 2, 3, 4, 5, 6]  
    >>> list1  
    [1, 2, 3, 4, 5, 6]
    

    Tại sao chỉ thay thay đổi list2list1 cũng bị thay đổi theo. Đây là lỗi rất hay mắc phải đối với người mới tìm hiểu về Python khi cố gắng tạo ra một bản copy của một list nào đó. Việc gán list2 = list1 thực chất chỉ là tạo ra 2 định danh (lis1, list2) nhưng đều trỏ về một list được lưu trữ trong bộ nhớ (cái này giống với pointer - con trỏ trong C, huh?). Điều này cũng đúng với cấu trúc dữ liệu khác như dictionary.

    Python xây dựng sẵn một lệnh list() dành cho việc copy list.

    >>> list3 = list(list1)  
    >>> list1  
    [1, 2, 3, 4, 5, 6]  
    >>> list3  
    [1, 2, 3, 4, 5, 6]  
    >>> list3.remove(3)  
    >>> list3  
    [1, 2, 4, 5, 6]  
    >>> list1  
    [1, 2, 3, 4, 5, 6]  
    >>> import copy  
    >>> list4 = copy.copy(list1)
    >>> list4.append(10)  
    [1, 2, 3, 4, 5, 6, 10]
    >>> list1  
    [1, 2, 3, 4, 5, 6]
    

    Nhưng đối với dict nếu chúng ta dùng lệnh dict() để copy dict thì lại không đúng:

    >>> dict1 = { 'a': {'x1' : 20, 'y1' : 40}, 'b': {'x2' : 15, 'y2' : 30} }  
    >>> dict2 = dict(dict1)  
    >>> dict2  
    {'a': {'x1': 20, 'y1': 40}, 'b': {'x2' : 15, 'y2': 30}}  
    >>> dict2['a']['z1'] = 60  
    >>>  
    >>> dict2  
    {'a': {'x1': 20, 'y1': 40, 'z1': 60}, 'b': {'x2': 15, 'y2': 30}}  
    >>> dict1  
    {'a': {'x1': 20, 'y1': 40, 'z1': 60}, 'b': {'x2': 15, 'y2': 30}}  
    

    Với trường hợp này chúng ta dùng phương thức deepcopy của thư viện copy.

    >>> import copy
    >>> dict3 = { 'a': {'x1' : 20, 'y1' : 40}, 'b': {'x2' : 15, 'y2' : 30} }  
    >>> dict4 = copy.deepcopy(dict3)  
    >>> dict4  
    {'a': {'x1': 20, 'y1': 40}, 'b': {'x2' : 15, 'y2': 30}}  
    >>> dict4['a']['z1'] = 60  
    >>>  
    >>> dict4  
    {'a': {'x1': 20, 'y1': 40, 'z1': 60}, 'b': {'x2': 15, 'y2': 30}}  
    >>> dict3
    {'a': {'x1' : 20, 'y1' : 40}, 'b': {'x2' : 15, 'y2' : 30}}
    

    Hãy dùng nó khi mà các cách copy khác không hoạt động

    8. Generators

    Cái này liên quan đến range()xrange() trong Python 2.x.x

    Generator trong Python cung cấp cho chúng ta một khái niệm đó là lazy evaluation. Trong Python 2 thì hàm xrange() chính là một generator (ví dụ khi thực hiện một vòng lặp chúng ta dùng range(6) chẳng hạn, nó sẽ tạo ra một list [0,1,2,3,4,5] và lưu trữ list đó trong bộ nhớ. Nhưng nếu chúng ta sử dụng xrange(6) thay vì range(6) thì tác dụng cũng tương tự nhưng xrange(6) sẽ không lưu trữ 1 list trong bộ nhớ mà nó sẽ tạo ra list [0,1,2,3,4,5] trong "tưởng tượng" và sẽ gọi từng số khi nào vòng lặp chạy đến số đó nên sẽ tiết kiệm bộ nhớ hơn so với range()).

    Python 3 chỉ sử dụng range() mà không có xrange() nữa, nhưng range() trong Python 3 lại giống với xrange() cũ.

    >>> [i for i in range(10)]  
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  
    >>> [i for i in xrange(10)]  
    Traceback (most recent call last):  
    File "", line 1, in  
    NameError: name xrange is not defined 
    

    Bạn có thể đọc thêm về Generator. Hãy nhìn đoạn code sau:

    >>> list1 = ['adam', 'bob', 'chris', 'dave']
    >>> gen1 = (x for x in list1)  
    >>> gen1  
    <generator object <genexpr> at 0x1006a68c0>  
    >>> for i in gen1:  
    ... print(i)  
    ...
    adam  
    bob  
    chris  
    dave  
    >>> for i in gen1:  
    ... print(i)  
    ...
    >>>
    

    dòng gen1 = (x for x in list) chính là tạo một generator (nếu thay () bằng [] thì sẽ tạo một list), sau đó gọi gen1 thì nó chỉ trả về vùng bộ nhớ mà nó đã đánh dấu. Điều đặc biệt ở đây là sau khi sử dụng cho khối lặp thứ nhất thì đến khối lặp thứ hai chúng ta không thể sử dụng gen1 nữa.

    Để hiểu hơn về generator, bạn có thể sử dụng kết hợp với yield trong Python. Đọc trang Stack Overflow question and answer này, bạn sẽ học được rất nhiều về generator.

    9. File Management

    Rất nhiều scripts mà chúng ta viết sử dụng các file để lấy dữ liệu đầu vào. Tài liệu chính thức của Python có giải thích về từ khóa open để dùng cho việc này. Bạn có thể lặp qua file để đọc từng dòng trong file, ngoài ra, cũng có thể sử dụng phương thức readlines() để tạo một list chứa các dòng của file, nhưng hãy thận trọng nếu file đó cực kỳ lớn nhé.

    f = open('test.txt', 'r')  
    for line in f:  
       # Đọc từng dòng trong file  
    f.close() 
    

    Ở đây f.close() rất quan trọng. Sau khi sử dụng xong file nào đó thì hãy close nó lại để giải phóng tài nguyên cho hệ thống và tránh sự trùng lặp sau này.

    Nhưng có một cách rất hữu dụng mà chúng ta không cần đến f.close() mỗi khi làm việc với file đó là sử dụng từ khóa with.

    # sys.argv[1] là một file, và 'r' nghĩa là chúng ta đang đọc nó
    with open(sys.argv[1], 'r') as feature_file:  
       all_lines = feature_file.readlines()  
       for i in xrange(len(all_lines)):  
          # Do stuff here
    

    with sẽ tự động close file sau khi khối lệnh được thực thi xong nên tôi khuyến nghị sử dụng with bởi vì chúng ta thường quên f.close() sau khi làm việc với file và đó là một điều rất tệ hại đấy !

    10. Class và Function (Hàm)

    Function thì không cần nói nhiều nữa, chúng ta sử dụng từ khóa def để định nghĩa hàm. Hàm rất quan trọng trong Python và cả trong các ngôn ngữ khác, nó giúp chúng ta tiết kiệm rất nhiều thời gian khi viết code.

    def count_zeroes(string):  # Đếm các số 0 trong một chuỗi
       total = 0  
       for c in string:  
          if c == 0:  
             total += 1  
       return total
    
    print(count_zeroes('00102')) # Will return 3  
    

    Cả hàm và class đều rất quan trọng trong các ngôn ngữ hướng đối tượng mà Python chính là một ngôn ngữ hướng đối tượng nên hãy bỏ thời gian tìm hiểu về Class và xem những ví dụ đơn giản về class ở đây.

    Lời kết

    Hãy dành thời gian thực hành thật nhiều và sử dụng Google cho những vấn đề bạn mắc phải. Ngoài ra nếu bạn thật sự thích thú với Python, hãy xem qua Stack Overflow question và tìm đọc những cấu trả lời có lượt vote cao nhất.



  • Bài gửi này đã bị xóa!

Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới Cộng đồng Python Việt Nam, vui lòng đợi một lúc để chúng tôi thử kết nối lại.