Modules

Khái niệm cơ bản về module trong Python

Module là một phần của chương trình Python, chứa các định nghĩa, biến và hàm được đóng gói lại để sử dụng trong các chương trình Python khác. Mỗi module trong Python là một file độc lập, chứa các định nghĩa và lời gọi hàm, và được thiết kế để giải quyết các vấn đề cụ thể trong lập trình Python.

Vai trò của module trong Python là tạo ra một phạm vi cho các biến, hàm và lớp được định nghĩa trong module, giúp chúng được tái sử dụng và tránh việc trùng lặp trong chương trình. Với module, chúng ta có thể chia sẻ các định nghĩa và chức năng giữa các chương trình Python khác nhau, giúp cho việc phát triển và bảo trì chương trình dễ dàng hơn.

Các module trong Python được sử dụng bằng cách sử dụng câu lệnh import trong chương trình Python, cho phép chương trình gọi các hàm và biến từ module đó. Các module phổ biến trong Python bao gồm NumPy, Pandas, Matplotlib, Scikit-learn, TensorFlow, Django, Flask, Pygame, Kivy, v.v.

Từ khóa import trong Python có thể được sử dụng để nhập một module hoặc một phần của nó. Ví dụ:

import math
from math import pi

Module là một phần cực kỳ quan trọng trong lập trình Python, giúp cho việc phát triển và bảo trì chương trình dễ dàng hơn, tránh việc trùng lặp mã và tăng tính sử dụng lại của các chức năng và biến. Do đó, hiểu rõ khái niệm cơ bản về module trong Python rất quan trọng đối với các lập trình viên Python.

Thực hành tạo module

Để tạo module riêng của bạn trong Python, bạn cần thực hiện các bước sau:

  1. Tạo một file Python mới và đặt tên cho file theo tên của module bạn muốn tạo.
  2. Định nghĩa các biến, hàm, lớp và phương thức mà bạn muốn thêm vào module của bạn.
  3. Sử dụng câu lệnh import để sử dụng module của bạn trong các chương trình khác.

Ví dụ, để tạo một module tính toán đơn giản trong Python, bạn có thể thực hiện các bước sau:

  1. Tạo một file Python mới và đặt tên cho file là simple_math.py

  2. Trong file simple_math.py, bạn có thể định nghĩa các hàm để tính toán như sau:

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    return a / b

Bây giờ, bạn có thể sử dụng module simple_math của bạn trong các chương trình Python khác bằng cách sử dụng câu lệnh import. Ví dụ:

import simple_math

print(simple_math.add(2, 3)) # 5
print(simple_math.subtract(5, 2)) # 3
print(simple_math.multiply(4, 6)) # 24
print(simple_math.divide(10, 2)) # 5.0

Khi trình thông dịch gặp một câu lệnh import, nếu module đó tồn tại trong đường dẫn tìm kiếm thì module sẽ được import vào. Đường dẫn tìm kiếm là một danh sách các thư mục mà trình thông dịch tìm kiếm trước khi import module.

Một module chỉ được tải một lần, bất kể số lần mà nó được import. Điều này ngăn chặn việc thực thi module xảy ra nhiều lần nếu có nhiều lần import

Để chia sẻ module của bạn với cộng đồng Python, bạn có thể đăng ký tài khoản trên PyPI (Python Package Index) và đăng tải module của bạn trên đó để người dùng khác có thể tìm thấy và sử dụng module của bạn. Bạn có thể sử dụng các công cụ như setuptools để tạo package và đăng tải nó lên PyPI.

Lệnh from…import

Lệnh from trong Python cho phép bạn import các thuộc tính cụ thể từ một module vào không gian tên hiện tại. Cú pháp của lệnh from…import như sau:

from modname import name1[, name2[, ... nameN]]

Ví dụ, để import hàm fibonacci từ module fib, bạn sử dụng câu lệnh sau:

from fib import fibonacci

Câu lệnh này không import toàn bộ module fib vào không gian tên hiện tại mà chỉ giới thiệu mục fibonacci từ module fib vào bảng ký hiệu toàn cục của module nhập khẩu.

Lệnh from…import *

Bạn cũng có thể nhập tất cả tên từ một module vào namespace hiện tại bằng cách sử dụng lệnh nhập sau đây:

from modname import *

Điều này cung cấp một cách dễ dàng để nhập tất cả các mục từ một module vào namespace hiện tại; tuy nhiên, lệnh này nên được sử dụng ít hơn.

Xác định vị trí của Modules Khi bạn nhập một module, trình thông dịch Python tìm kiếm module trong các chuỗi sau đây:

Thư mục hiện tại.

Nếu không tìm thấy module, Python sẽ tìm kiếm từng thư mục trong biến môi trường PYTHONPATH.

Nếu tất cả mọi thứ đều thất bại, Python sẽ kiểm tra đường dẫn mặc định. Trên UNIX, đường dẫn mặc định này thường là /usr/local/lib/python/.

Đường dẫn tìm kiếm module được lưu trữ trong module hệ thống sys dưới dạng biến sys.path. Biến sys.path chứa thư mục hiện tại, PYTHONPATH và đường dẫn mặc định phụ thuộc vào việc cài đặt.

Biến môi trường PYTHONPATH

PYTHONPATH là một biến môi trường, bao gồm một danh sách các thư mục. Cú pháp của PYTHONPATH giống với biến môi trường PATH của shell.

Đây là một PYTHONPATH điển hình trên hệ thống Windows −

set PYTHONPATH = c:\python20\lib;

Và đây là một PYTHONPATH điển hình trên hệ thống UNIX −

set PYTHONPATH = /usr/local/lib/python

Không gian tên và Phạm vi

Biến là các tên (định danh) được ánh xạ tới các đối tượng. Một không gian tên là một từ điển của các tên biến (khóa) và các đối tượng tương ứng của chúng (giá trị).

Một câu lệnh Python có thể truy cập các biến trong không gian tên cục bộ và trong không gian tên toàn cục. Nếu một biến cục bộ và một biến toàn cục có cùng tên, biến cục bộ sẽ che khuất biến toàn cục.

Mỗi hàm có không gian tên cục bộ riêng của nó. Các phương thức lớp tuân theo cùng quy tắc phạm vi như các hàm bình thường.

Python đoán định thông minh xem biến có phải là cục bộ hay toàn cục. Nó giả định rằng bất kỳ biến được gán giá trị trong một hàm đều là cục bộ.

Do đó, để gán giá trị cho một biến toàn cục trong một hàm, bạn phải sử dụng câu lệnh global trước.

Câu lệnh global VarName cho biết với Python rằng VarName là một biến toàn cục. Python sẽ ngừng tìm kiếm không gian tên cục bộ cho biến đó.

Ví dụ, chúng ta định nghĩa một biến Money trong không gian tên toàn cục. Trong hàm Money, chúng ta gán Money một giá trị, do đó Python giả định Money là một biến cục bộ. Tuy nhiên, trước khi gán giá trị cho Money, chúng ta truy cập giá trị của biến cục bộ Money, vì vậy kết quả là UnboundLocalError. Việc gỡ bỏ chú thích trong câu lệnh global sẽ khắc phục vấn đề này.

Money = 2000
def AddMoney():
   # Bỏ chú thích cho câu lệnh bên dưới là hết lỗi:
   # global Money
   Money = Money + 1

print Money
AddMoney()
print Money

Hàm dir()

Hàm dir() được tích hợp sẵn và trả về một danh sách được sắp xếp các chuỗi chứa các tên được định nghĩa bởi một module.

Danh sách chứa tên của tất cả các module, biến và hàm được định nghĩa trong module. Sau đây là một ví dụ đơn giản −

# Nhập module toán học tích hợp sẵn
import math

content = dir(math)
print(content)

Khi mã trên được thực thi, nó sẽ tạo ra kết quả sau −

['doc', 'file', 'name', 'acos', 'asin', 'atan',
'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp',
'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh',
'sqrt', 'tan', 'tanh']

Ở đây, biến chuỗi đặc biệt name là tên module, và file là tên tệp từ đó module được tải.

Các hàm globals() và locals()

Các hàm globals() và locals() có thể được sử dụng để trả về các tên trong các không gian tên toàn cục và cục bộ tùy thuộc vào vị trí mà chúng được gọi từ đó.

Nếu locals() được gọi từ bên trong một hàm, nó sẽ trả về tất cả các tên có thể truy cập được cục bộ từ hàm đó.

Nếu globals() được gọi từ bên trong một hàm, nó sẽ trả về tất cả các tên có thể truy cập được toàn cục từ hàm đó.

Kiểu trả về của cả hai hàm này là từ điển. Do đó, các tên có thể được trích xuất bằng cách sử dụng hàm keys().

Hàm reload()

Khi module được nhập vào một kịch bản, mã trong phần cấp độ cao nhất của module chỉ được thực thi một lần.

Do đó, nếu bạn muốn thực thi lại mã cấp độ cao nhất trong một module, bạn có thể sử dụng hàm reload(). Hàm reload() nhập một module đã được nhập trước đó một lần nữa. Cú pháp của hàm reload() là

reload(module_name)

Ở đây, module_name là tên của module mà bạn muốn nạp lại và không phải là chuỗi chứa tên module. Ví dụ, để nạp lại module hello, hãy làm như sau −

reload(hello)

Các Gói (Packages) trong Python

Trong Python, package là một tập hợp các module (được lưu trữ trong các file .py) và các thư mục con của chúng. Chúng ta có thể sử dụng các package để sắp xếp và quản lý các module và class của mình.

Một package có thể chứa các module, các subpackage, các tệp tin cấu hình, các file dữ liệu, các tệp tin khởi tạo (init.py) và các thành phần khác Dưới đây là một ví dụ đơn giản về cách xây dựng một package trong Python.

Giả sử chúng ta muốn xây dựng một package có tên là “my_package”, và gồm một số module như sau:

my_module1.py: chứa một hàm tính tổng hai số. my_module2.py: chứa một hàm tính tổng ba số. Bước 1: Tạo thư mục cho package và các module của nó. Tạo một thư mục có tên là “my_package” và tạo hai tệp tin my_module1.py và my_module2.py trong đó.

my_package/
├── __init__.py
├── my_module1.py
└── my_module2.py

Bước 2: Trong mỗi tệp tin my_module1.py và my_module2.py, chúng ta định nghĩa các hàm của chúng ta.

Ví dụ, trong my_module1.py, chúng ta có thể định nghĩa hàm tính tổng hai số như sau:

def sum_two_numbers(a, b):
    return a + b

Trong my_module2.py, chúng ta có thể định nghĩa hàm tính tổng ba số như sau:

def sum_three_numbers(a, b, c):
    return a + b + c

Bước 3: Trong tệp tin init.py, chúng ta định nghĩa chúng ta định nghĩa các module của package

from .my_module1 import sum_two_numbers
from .my_module2 import sum_three_numbers

Bước 4: Kiểm tra package. Bây giờ chúng ta có thể kiểm tra package của mình bằng cách tạo một tệp tin test.py và sử dụng các hàm của package như sau:

import my_package

print(my_package.sum_two_numbers(1, 2)) # Kết quả: 3
print(my_package.sum_three_numbers(1, 2, 3)) # Kết quả: 6

Với các bước trên, chúng ta đã tạo thành một package đơn giản có hai module my_module1.py và my_module2.py và có thể sử dụng các hàm của chúng trong tệp tin test.py.

Bình luận