Các Khái Niệm Cốt Lõi và Kỹ Thuật Nâng Cao trong Python Hiện Đại

Để thay đổi giá trị biến toàn cục bên trong hàm, có hai cách phổ biến:

a = 1

def update_global_via_dict():
    globals()['a'] = 42

print('Giá trị ban đầu:', a)
update_global_via_dict()
print('Sau khi cập nhật:', a)

Kết quả xuất ra:

Giá trị ban đầu: 1
Sau khi cập nhật: 42

Cách thứ hai rõ ràng và được khuyến nghị hơn:

def update_global_with_keyword():
    global a
    a = 42

Khóa Toàn Cục Trình Thông Dịch (GIL)

GIL (Global Interpreter Lock) là cơ chế đồng bộ hóa trong CPython nhằm đảm bảo chỉ một luồng thực thi bytecode Python tại một thời điểm trong cùng một tiến trình. Điều này ngăn chặn hiện tượng truy cập đồng thời vào cấu trúc dữ liệu nội bộ của trình thông dịch — nhưng cũng khiến đa luồng không tận dụng được CPU đa nhân cho công việc tính toán thuần Python. Khi luồng gặp I/O hoặc gọi hàm ngoại (như time.sleep(), requests.get()), GIL thường được giải phóng, cho phép luồng khác chạy. Với tải trọng tính toán nặng, giải pháp hiệu quả hơn là sử dụng multiprocessing — mỗi tiến trình có riêng một GIL và bộ nhớ độc lập.

Xử Lý Danh Sách: Loại Bỏ Phần Tử Trùng Lặp

Sử dụng tập hợp để loại bỏ trùng lặp — nhanh và ngắn gọn, nhưng không giữ thứ tự:

data = [5, 3, 3, 8, 5, 9]
unique_data = list(set(data))
print(unique_data)  # Thứ tự không đảm bảo, ví dụ: [3, 5, 8, 9]

Nếu cần duy trì thứ tự chèn, dùng vòng lặp với danh sách tạm:

data = [5, 3, 3, 8, 5, 9]
seen = set()
ordered_unique = []
for item in data:
    if item not in seen:
        seen.add(item)
        ordered_unique.append(item)
print(ordered_unique)  # [5, 3, 8, 9]

Tính Bất Biến và Tính Thay Đổi của Kiểu Dữ Liệu

Các kiểu bất biến (immutable): int, str, tuple. Khi "thay đổi" giá trị, thực chất là tạo đối tượng mới:

x = "hello"
y = "hello"
print(id(x) == id(y))  # True — cùng trỏ đến đối tượng chuỗi trong vùng nhớ interned

z = x + " world"  # Tạo chuỗi mới; x vẫn giữ giá trị gốc

Các kiểu khả biến (mutable): list, dict, set. Các thao tác như .append(), .update() thay đổi nội dung đối tượng tại chỗ:

list_a = [1, 2]
list_b = list_a.copy()  # hoặc list_a[:]
list_b.append(3)
print(list_a)  # [1, 2] — không bị ảnh hưởng
print(list_b)  # [1, 2, 3]

Chuyển Đổi Giữa Python 2 và Python 3

  • print trở thành hàm bắt buộc dấu ngoặc: print("Hi").
  • range() trả về đối tượng range (iterator), không phải danh sách — tiết kiệm bộ nhớ.
  • Mã hóa mặc định chuyển từ ASCII sang UTF-8.
  • input() thay thế raw_input(); input() trong Python 2 tương đương eval(input()) — gây rủi ro bảo mật.
  • Không còn kiểu long; int hỗ trợ độ chính xác vô hạn.

Các Cấu Trúc Dữ Liệu Nội Tại Chính

Bao gồm: int, float, complex, str, list, tuple, dict, set, frozenset, bytes, bytearray, bool.

Hành Vi Của Cắt Mảng Ngoài Giới Hạn

Truy cập phần tử bằng chỉ số vượt quá kích thước danh sách gây IndexError. Tuy nhiên, cắt mảng (slicing) với chỉ số bắt đầu lớn hơn độ dài sẽ trả về danh sách rỗng — không ném ngoại lệ:

items = ['a', 'b']
print(items[10:])   # []
print(items[10:20]) # []

Tham Số Linh Động: *args và **kwargs

*args thu thập các đối số vị trí dư thừa thành một tuple. **kwargs thu thập các đối số từ khóa dư thừa thành một dict. Chúng cho phép xây dựng hàm linh hoạt, dễ mở rộng:

def configure_server(host, port, *plugins, **options):
    print(f"Kết nối {host}:{port}")
    print("Plugin đã tải:", plugins)
    print("Tùy chọn bổ sung:", options)

configure_server("localhost", 8080, "auth", "cache", timeout=30, debug=True)

Một Số Thư Viện Chuẩn Quan Trọng

  • pathlib: Xử lý đường dẫn theo hướng đối tượng, thay thế os.path.
  • json: Mã hóa/giải mã dữ liệu JSON.
  • itertools: Cung cấp các công cụ lặp hiệu quả (ví dụ: chain, groupby).
  • functools: Hỗ trợ lập trình hàm (ví dụ: lru_cache, partial).
  • concurrent.futures: Giao diện thống nhất cho đa luồng/multi-process.

Một Số Phương Thức Đặc Biệt Thường Dùng

  • __init__: Hàm khởi tạo đối tượng.
  • __str__: Định nghĩa biểu diễn chuỗi cho print()str().
  • __repr__: Cung cấp biểu diễn "có thể tái tạo", dành cho gỡ lỗi.
  • __len__: Cho phép dùng len(obj).
  • __getitem__: Hỗ trợ indexing như obj[key] hoặc slicing.

So Sánh os và sys

os cung cấp giao diện tương tác với hệ điều hành: quản lý tệp, thư mục, môi trường, tiến trình con. sys cung cấp quyền kiểm soát runtime của Python: tham số dòng lệnh (sys.argv), đường dẫn tìm module (sys.path), giới hạn đệ quy (sys.setrecursionlimit), và luồng nhập/xuất chuẩn.

Cơ Chế Quản Lý Bộ Nhớ Cơ Bản

CPython chủ yếu dựa vào đếm tham chiếu: mỗi đối tượng lưu số lượng biến đang trỏ tới nó. Khi đếm giảm về 0, bộ nhớ được giải phóng ngay lập tức. Để xử lý vòng lặp tham chiếu (ví dụ: hai đối tượng giữ tham chiếu lẫn nhau), trình thu gom rác sử dụng thuật toán đánh dấu–dọn dẹpphân thế hệ (generational collection).

Phân Biệt Gán, Sao Chép Nông và Sao Chép Sâu

  • Gán trực tiếp: Hai tên cùng trỏ tới một đối tượng.
  • Sao chép nông (copy.copy()): Tạo bản sao mới của đối tượng ngoài cùng, nhưng các phần tử lồng nhau vẫn chia sẻ tham chiếu.
  • Sao chép sâu (copy.deepcopy()): Tạo bản sao hoàn toàn độc lập ở mọi cấp độ — thay đổi ở bản sao không ảnh hưởng bản gốc.

Xử Lý Chuỗi Với Thư Viện re

  • re.split(pattern, string): Chia chuỗi thành danh sách dựa trên mẫu regex.
  • re.sub(pattern, repl, string): Thay thế tất cả kết quả khớp bằng chuỗi hoặc hàm thay thế.
  • re.subn(pattern, repl, string): Tương tự sub(), nhưng trả về tuple (chuỗi_mới, số_lần_thay_thế).

sort() vs sorted()

list.sort() sắp xếp tại chỗ — không trả về giá trị (trả về None), chỉ áp dụng cho list. sorted() là hàm tổng quát nhận bất kỳ iterable nào, luôn trả về danh sách mới — phù hợp với tuple, dict (sắp xếp key), set, v.v.

Phân Loại Phương Thức Trong Lớp

  • Phương thức thể hiện (instance method): Nhận self làm tham số đầu tiên; truy cập thuộc tính và phương thức thể hiện.
  • Phương thức lớp (@classmethod): Nhận cls — truy cập thuộc tính và phương thức lớp, hữu ích cho các phương thức tạo (factory methods).
  • Phương thức tĩnh (@staticmethod): Không nhận self hay cls; giống hàm bình thường nhưng nằm trong phạm vi lớp — dùng để nhóm logic liên quan.

Lập Trình Thiết Kế: Mẫu Singleton

Một cách triển khai sạch và thread-safe sử dụng __new__:

class Singleton:
    _instance = None
    _initialized = False

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not self._initialized:
            self.config = {"debug": True}
            self._initialized = True

# Sử dụng
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True

Thẻ: python gil mutable-immutable singleton decorator

Đăng vào ngày 18 tháng 6 lúc 01:48