Để 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
printtrở thành hàm bắt buộc dấu ngoặc:print("Hi").range()trả về đối tượngrange(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 đươngeval(input())— gây rủi ro bảo mật.- Không còn kiểu
long;inthỗ 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 choprint()và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ùnglen(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ẹp và phâ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
selflà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ậncls— 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ậnselfhaycls; 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