Thư viện và tiện ích mở rộng FAQ

Câu hỏi thư viện tổng hợp

Làm cách nào để tìm mô-đun hoặc ứng dụng để thực hiện tác vụ X?

Kiểm tra the Library Reference để xem có mô-đun thư viện tiêu chuẩn phù hợp hay không. (Cuối cùng, bạn sẽ tìm hiểu nội dung trong thư viện chuẩn và có thể bỏ qua bước này.)

Đối với các gói của bên thứ ba, hãy tìm kiếm Python Package Index hoặc thử Google hoặc một công cụ tìm kiếm web khác. Tìm kiếm "Python" cộng với một hoặc hai từ khóa cho chủ đề bạn quan tâm thường sẽ tìm thấy điều gì đó hữu ích.

Tệp nguồn math.py (socket.py, Regex.py, v.v.) ở đâu?

Nếu bạn không thể tìm thấy tệp nguồn cho mô-đun thì đó có thể là mô-đun được tích hợp sẵn hoặc được tải động được triển khai bằng C, C++ hoặc ngôn ngữ được biên dịch khác. Trong trường hợp này, bạn có thể không có tệp nguồn hoặc nó có thể giống như mathmodule.c, ở đâu đó trong thư mục nguồn C (không phải trên Đường dẫn Python).

Có (ít nhất) ba loại mô-đun trong Python:

  1. các mô-đun được viết bằng Python (.py);

  2. các mô-đun được viết bằng C và được tải động (.dll, .pyd, .so, .sl, v.v.);

  3. các mô-đun viết bằng C và được liên kết với trình thông dịch; để có danh sách những thứ này, hãy gõ:

    hệ thống nhập khẩu
    in(sys.buildin_module_names)
    

Làm cách nào để tạo tập lệnh Python có thể thực thi được trên Unix?

Bạn cần thực hiện hai điều: chế độ của tệp tập lệnh phải có thể thực thi được và dòng đầu tiên phải bắt đầu bằng #!, theo sau là đường dẫn của trình thông dịch Python.

Việc đầu tiên được thực hiện bằng cách thực thi chmod +x scriptfile hoặc có lẽ chmod 755 scriptfile.

Việc thứ hai có thể được thực hiện bằng nhiều cách. Cách đơn giản nhất là viết

#!/usr/local/bin/python

làm dòng đầu tiên trong tệp của bạn, sử dụng tên đường dẫn nơi cài đặt trình thông dịch Python trên nền tảng của bạn.

Nếu bạn muốn tập lệnh độc lập với vị trí của trình thông dịch Python, bạn có thể sử dụng chương trình env. Hầu hết tất cả các biến thể Unix đều hỗ trợ những điều sau, giả sử trình thông dịch Python nằm trong một thư mục trên PATH:: của người dùng.

#!/usr/bin/env trăn

Don't thực hiện việc này cho tập lệnh CGI. Biến PATH cho tập lệnh CGI thường rất tối thiểu, vì vậy bạn cần sử dụng tên đường dẫn tuyệt đối thực tế của trình thông dịch.

Đôi khi, môi trường của người dùng quá đầy khiến chương trình /usr/bin/env bị lỗi; hoặc không có chương trình env nào cả. Trong trường hợp đó, bạn có thể thử cách hack sau (do Alex Rezinsky):

#! /bin/sh
"": //
thực thi trăn $0 ${1+"$@"}
"""

Nhược điểm nhỏ là điều này xác định chuỗi __doc__ của tập lệnh. Tuy nhiên, bạn có thể khắc phục điều đó bằng cách thêm

__doc__ = """...Sao cũng được..."""

Có gói lời nguyền/termcap cho Python không?

Đối với các biến thể Unix: Bản phân phối nguồn Python tiêu chuẩn đi kèm với mô-đun lời nguyền trong thư mục con Modules, mặc dù nó không được biên dịch theo mặc định. (Lưu ý rằng tính năng này không có sẵn trong bản phân phối Windows -- không có mô-đun lời nguyền cho Windows.)

Mô-đun curses hỗ trợ các tính năng lời nguyền cơ bản cũng như nhiều chức năng bổ sung từ các lời nguyền ncurses và SYSV như màu sắc, hỗ trợ bộ ký tự thay thế, miếng đệm và hỗ trợ chuột. Điều này có nghĩa là mô-đun này không tương thích với các hệ điều hành chỉ có lỗi BSD, nhưng dường như không có bất kỳ hệ điều hành nào hiện được duy trì thuộc loại này.

Có tương đương với onexit() của C trong Python không?

Mô-đun atexit cung cấp chức năng đăng ký tương tự như onexit() của C.

Tại sao bộ xử lý tín hiệu của tôi không hoạt động?

Vấn đề phổ biến nhất là trình xử lý tín hiệu được khai báo với danh sách đối số sai. Nó được gọi là

trình xử (dấu hiệu, khung)

vì vậy nó phải được khai báo với hai tham số

trình xử  def (dấu hiệu, khung):
    ...

Nhiệm vụ chung

Làm cách nào để kiểm tra chương trình hoặc thành phần Python?

Python đi kèm với hai khung thử nghiệm. Mô-đun doctest tìm các ví dụ trong chuỗi tài liệu cho một mô-đun và chạy chúng, so sánh kết quả đầu ra với kết quả mong đợi được cung cấp trong chuỗi tài liệu.

Mô-đun unittest là một khung thử nghiệm phức tạp hơn được mô hình hóa dựa trên các khung thử nghiệm Java và Smalltalk.

Để làm cho việc kiểm tra dễ dàng hơn, bạn nên sử dụng thiết kế mô-đun tốt trong chương trình của mình. Chương trình của bạn phải có hầu hết tất cả chức năng được gói gọn trong các hàm hoặc phương thức lớp -- và điều này đôi khi có tác dụng đáng ngạc nhiên và thú vị là làm cho chương trình chạy nhanh hơn (vì truy cập biến cục bộ nhanh hơn truy cập biến toàn cục). Hơn nữa, chương trình nên tránh phụ thuộc vào việc thay đổi các biến toàn cục, vì điều này khiến việc kiểm tra khó thực hiện hơn nhiều.

"Logic chính toàn cục" của chương trình của bạn có thể đơn giản như

nếu __name__ == "__main__":
    main_logic()

ở cuối mô-đun chính của chương trình của bạn.

Khi chương trình của bạn được tổ chức dưới dạng một tập hợp các hành vi của hàm và lớp có thể điều khiển được, bạn nên viết các hàm kiểm tra để thực hiện các hành vi đó. Một bộ thử nghiệm tự động hóa một chuỗi thử nghiệm có thể được liên kết với mỗi mô-đun. Điều này nghe có vẻ tốn nhiều công sức, nhưng vì Python rất ngắn gọn và linh hoạt nên nó dễ dàng một cách đáng ngạc nhiên. Bạn có thể làm cho việc viết mã trở nên dễ chịu và thú vị hơn nhiều bằng cách viết các hàm kiểm tra song song với "mã sản xuất", vì điều này giúp bạn dễ dàng tìm ra lỗi và thậm chí cả lỗi thiết kế trước đó.

"Mô-đun hỗ trợ" không nhằm mục đích trở thành mô-đun chính của chương trình có thể bao gồm việc tự kiểm tra mô-đun.

nếu __name__ == "__main__":
    self_test()

Ngay cả các chương trình tương tác với giao diện bên ngoài phức tạp cũng có thể được kiểm tra khi giao diện bên ngoài không khả dụng bằng cách sử dụng giao diện "giả" được triển khai bằng Python.

Làm cách nào để tạo tài liệu từ chuỗi tài liệu?

Mô-đun pydoc có thể tạo HTML từ chuỗi tài liệu trong mã nguồn Python của bạn. An alternative for creating API documentation purely from docstrings is epydoc. Sphinx cũng có thể bao gồm nội dung chuỗi tài liệu.

Làm cách nào để tôi có thể nhấn một phím cùng một lúc?

Đối với các biến thể Unix có một số giải pháp. Thật đơn giản để thực hiện việc này bằng cách sử dụng lời nguyền, nhưng lời nguyền là một mô-đun khá lớn để học.

chủ đề

Làm cách nào để lập trình bằng cách sử dụng các chủ đề?

Đảm bảo sử dụng mô-đun threading chứ không phải mô-đun _thread. Mô-đun threading xây dựng các phần trừu tượng thuận tiện dựa trên các nguyên hàm cấp thấp do mô-đun _thread cung cấp.

Không có chủ đề nào của tôi dường như chạy: tại sao?

Ngay khi luồng chính thoát ra, tất cả các luồng sẽ bị hủy. Luồng chính của bạn đang chạy quá nhanh, khiến các luồng không có thời gian để thực hiện bất kỳ công việc nào.

Cách khắc phục đơn giản là thêm chế độ ngủ vào cuối chương trình đủ lâu để tất cả các luồng kết thúc

nhập luồng, thời gian

def thread_task(tên, n):
    cho tôi trong phạm vi (n):
        in(tên, tôi)

cho tôi trong phạm vi (10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10) # <--------------------------!

Nhưng bây giờ (trên nhiều nền tảng), các luồng không chạy song song mà dường như chạy tuần tự, từng luồng một! Lý do là bộ lập lịch luồng của hệ điều hành không bắt đầu một luồng mới cho đến khi luồng trước đó bị chặn.

Cách khắc phục đơn giản là thêm một giấc ngủ nhỏ vào đầu hàm chạy

def thread_task(tên, n):
    time.sleep(0.001) # <--------------------!
    cho tôi trong phạm vi (n):
        in(tên, tôi)

cho tôi trong phạm vi (10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

thời gian.ngủ(10)

Thay vì cố gắng đoán giá trị độ trễ phù hợp cho time.sleep(), tốt hơn hết bạn nên sử dụng một số loại cơ chế semaphore. Một ý tưởng là sử dụng mô-đun queue để tạo một đối tượng hàng đợi, cho phép mỗi luồng thêm một mã thông báo vào hàng đợi khi nó kết thúc và để luồng chính đọc bao nhiêu mã thông báo từ hàng đợi tùy theo số lượng luồng.

Làm cách nào để phân chia công việc giữa một loạt các luồng công nhân?

Cách dễ nhất là sử dụng mô-đun concurrent.futures, đặc biệt là lớp ThreadPoolExecutor.

Hoặc, nếu bạn muốn kiểm soát tốt thuật toán điều phối, bạn có thể viết logic của riêng mình theo cách thủ công. Sử dụng mô-đun queue để tạo hàng đợi chứa danh sách công việc. Lớp Queue duy trì một danh sách các đối tượng và có phương thức .put(obj) để thêm các mục vào hàng đợi và phương thức .get() để trả về chúng. Lớp sẽ đảm nhiệm việc khóa cần thiết để đảm bảo mỗi công việc được giao đúng một lần.

Đây là một ví dụ tầm thường

nhập luồng, hàng đợi, thời gian

Chuỗi công nhân # The loại bỏ công việc khỏi hàng đợi.  Khi hàng đợi trống, nó
# assumes sẽ không còn việc gì nữa và thoát ra.
# (Thực tế là các công nhân sẽ chạy cho đến khi bị chấm dứt.)
công nhân def():
    print('Nhân viên đang chạy')
    thời gian.ngủ (0,1)
    trong khi Đúng:
        thử:
            arg = q.get(block=False)
        ngoại trừ hàng đợi.Empty:
            print('Worker', threading.current_thread(), end=' ')
            print('hàng đợi trống')
            phá vỡ
        khác:
            print('Worker', threading.current_thread(), end=' ')
            print('chạy với đối số', arg)
            thời gian.ngủ (0,5)

hàng đợi # Create
q = hàng đợi.Queue()

# Start một nhóm gồm 5 công nhân
cho tôi trong phạm vi (5):
    t = threading.Thread(target=worker, name='worker %i' % (i+1))
    t.start()

# Begin thêm công việc vào hàng đợi
cho tôi trong phạm vi (50):
    q.put(i)

chủ đề # Give đã đến lúc chạy
print('Chủ đề chính đang ngủ')
thời gian.ngủ(5)

Khi chạy, điều này sẽ tạo ra đầu ra sau:

Công nhân chạy bộ
Công nhân chạy bộ
Công nhân chạy bộ
Công nhân chạy bộ
Công nhân chạy bộ
Chủ đề chính đang ngủ
Công nhân <Thread(worker 1, started 130283832797456)> đang chạy với đối số 0
Công nhân <Thread(worker 2, started 130283824404752)> đang chạy với đối số 1
Công nhân <Thread(worker 3, started 130283816012048)> đang chạy với đối số 2
Công nhân <Thread(worker 4, started 130283807619344)> đang chạy với đối số 3
Công nhân <Thread(worker 5, started 130283799226640)> đang chạy với đối số 4
Công nhân <Thread(worker 1, started 130283832797456)> đang chạy với đối số 5
...

Tham khảo tài liệu của mô-đun để biết thêm chi tiết; lớp Queue cung cấp một giao diện đầy tính năng.

Những loại đột biến giá trị toàn cầu nào an toàn cho luồng?

Một global interpreter lock (GIL) được sử dụng nội bộ để đảm bảo rằng mỗi lần chỉ có một luồng chạy trong máy ảo Python. Nói chung, Python chỉ đề xuất chuyển đổi giữa các luồng giữa các lệnh mã byte; tần suất chuyển đổi có thể được đặt thông qua sys.setswitchinterval(). Do đó, mỗi lệnh mã byte và do đó, tất cả mã triển khai C đạt được từ mỗi lệnh đều là mã nguyên tử theo quan điểm của chương trình Python.

Về lý thuyết, điều này có nghĩa là việc hạch toán chính xác đòi hỏi sự hiểu biết chính xác về việc triển khai mã byte PVM. Trong thực tế, điều đó có nghĩa là các thao tác trên các biến chung của các kiểu dữ liệu có sẵn (ints, list, dicts, v.v.) thực sự "trông nguyên tử".

Ví dụ: các thao tác sau đều là nguyên tử (L, L1, L2 là danh sách, D, D1, D2 là ký tự, x, y là đối tượng, i, j là int):

L.chắp thêm(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()

Đây không phải là:

tôi = tôi+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1

Các hoạt động thay thế các đối tượng khác có thể gọi phương thức __del__() của các đối tượng khác đó khi số tham chiếu của chúng đạt đến 0 và điều đó có thể ảnh hưởng đến mọi thứ. Điều này đặc biệt đúng đối với các bản cập nhật hàng loạt cho từ điển và danh sách. Khi nghi ngờ, hãy sử dụng mutex!

Chúng ta không thể loại bỏ Khóa phiên dịch toàn cầu sao?

global interpreter lock (GIL) thường được coi là trở ngại cho việc triển khai Python trên các máy chủ đa bộ xử lý cao cấp, bởi vì chương trình Python đa luồng chỉ sử dụng một CPU một cách hiệu quả, do nhấn mạnh rằng (gần như) tất cả mã Python chỉ có thể chạy trong khi GIL được giữ.

Với sự chấp thuận của PEP 703, công việc hiện đang được tiến hành để loại bỏ GIL khỏi quá trình triển khai CPython của Python. Ban đầu, nó sẽ được triển khai dưới dạng cờ trình biên dịch tùy chọn khi xây dựng trình thông dịch và do đó, các bản dựng riêng biệt sẽ có sẵn khi có và không có GIL. Về lâu dài, hy vọng sẽ ổn định trên một bản dựng duy nhất, sau khi hiểu đầy đủ về tác động của việc loại bỏ GIL về hiệu suất. Python 3.13 có thể là bản phát hành đầu tiên chứa tác phẩm này, mặc dù nó có thể không có đầy đủ chức năng trong bản phát hành này.

Công việc hiện tại để loại bỏ GIL dựa trên fork of Python 3.9 with the GIL removed của Sam Gross. Trước đó, vào thời của Python 1.5, Greg Stein thực sự đã triển khai một bộ bản vá toàn diện (các bản vá "phân luồng miễn phí") để loại bỏ GIL và thay thế nó bằng khóa chi tiết hơn. Adam Olsen đã thực hiện một thí nghiệm tương tự trong dự án python-safethread của mình. Thật không may, cả hai thử nghiệm trước đó đều cho thấy hiệu suất đơn luồng giảm mạnh (chậm hơn ít nhất 30%), do số lượng khóa chi tiết cần thiết để bù đắp cho việc loại bỏ GIL. Ngã ba Python 3.9 là nỗ lực đầu tiên nhằm loại bỏ GIL với tác động hiệu suất ở mức chấp nhận được.

Sự hiện diện của GIL trong các bản phát hành Python hiện tại không có nghĩa là bạn không thể sử dụng tốt Python trên các máy multi-CPU! Bạn chỉ cần sáng tạo trong việc phân chia công việc giữa nhiều processes thay vì nhiều threads. Lớp ProcessPoolExecutor trong mô-đun concurrent.futures mới cung cấp một cách dễ dàng để thực hiện việc đó; mô-đun multiprocessing cung cấp API cấp thấp hơn trong trường hợp bạn muốn kiểm soát nhiều hơn việc gửi nhiệm vụ.

Việc sử dụng hợp lý các phần mở rộng C cũng sẽ có ích; nếu bạn sử dụng tiện ích mở rộng C để thực hiện một tác vụ tốn thời gian, tiện ích mở rộng có thể giải phóng GIL trong khi luồng thực thi nằm trong mã C và cho phép các luồng khác hoàn thành một số công việc. Một số mô-đun thư viện tiêu chuẩn như zlibhashlib đã thực hiện việc này.

Một cách tiếp cận khác để giảm tác động của GIL là biến GIL thành khóa trạng thái cho mỗi phiên dịch viên thay vì thực sự toàn cầu. Đây là first implemented in Python 3.12 và có sẵn trong C API. Giao diện Python cho nó được mong đợi trong Python 3.13. Hạn chế chính của nó vào lúc này có thể là các mô-đun mở rộng của bên thứ 3, vì chúng phải được viết bằng nhiều trình thông dịch để có thể sử dụng được, vì vậy nhiều mô-đun mở rộng cũ hơn sẽ không thể sử dụng được.

Đầu vào và đầu ra

Làm cách nào để xóa một tập tin? (Và các câu hỏi về tập tin khác...)

Sử dụng os.remove(filename) hoặc os.unlink(filename); để biết tài liệu, hãy xem mô-đun os. Hai chức năng này giống hệt nhau; unlink() chỉ đơn giản là tên gọi hệ thống Unix cho chức năng này.

Để xóa một thư mục, hãy sử dụng os.rmdir(); sử dụng os.mkdir() để tạo một cái. os.makedirs(path) sẽ tạo bất kỳ thư mục trung gian nào trong path không tồn tại. os.removedirs(path) sẽ xóa các thư mục trung gian miễn là chúng trống; nếu bạn muốn xóa toàn bộ cây thư mục và nội dung của nó, hãy sử dụng shutil.rmtree().

Để đổi tên một tập tin, hãy sử dụng os.rename(old_path, new_path).

Để cắt bớt một tệp, hãy mở tệp đó bằng f = open(filename, "rb+") và sử dụng f.truncate(offset); bù đắp mặc định cho vị trí tìm kiếm hiện tại. Ngoài ra còn có os.ftruncate(fd, offset) cho các tệp được mở bằng os.open(), trong đó fd là bộ mô tả tệp (một số nguyên nhỏ).

Mô-đun shutil cũng chứa một số chức năng để hoạt động trên các tệp bao gồm copyfile(), copytree()rmtree().

Làm cách nào để sao chép một tập tin?

Mô-đun shutil chứa chức năng copyfile(). Lưu ý rằng trên các ổ NTFS của Windows, nó không sao chép alternate data streams hay resource forks trên các ổ HFS+ của macOS, mặc dù cả hai hiện nay hiếm khi được sử dụng. Nó cũng không sao chép quyền truy cập tệp và siêu dữ liệu, mặc dù thay vào đó, sử dụng shutil.copy2() sẽ bảo toàn hầu hết (mặc dù không phải tất cả) dữ liệu đó.

Làm cách nào để đọc (hoặc ghi) dữ liệu nhị phân?

Để đọc hoặc ghi các định dạng dữ liệu nhị phân phức tạp, tốt nhất bạn nên sử dụng mô-đun struct. Nó cho phép bạn lấy một chuỗi chứa dữ liệu nhị phân (thường là số) và chuyển đổi nó thành đối tượng Python; và ngược lại.

Ví dụ: đoạn mã sau đọc hai số nguyên 2 byte và một số nguyên 4 byte ở định dạng big-endian từ một tệp:

nhập cấu trúc

với open(filename, "rb")  f:
    s = f.read(8)
    x, y, z = struct.unpack(">hhl", s)

'>' trong chuỗi định dạng buộc phải có dữ liệu lớn; chữ cái 'h' đọc một "số nguyên ngắn" (2 byte) và 'l' đọc một "số nguyên dài" (4 byte) từ chuỗi.

Đối với dữ liệu thường xuyên hơn (ví dụ: danh sách int hoặc float đồng nhất), bạn cũng có thể sử dụng mô-đun array.

Ghi chú

Để đọc và ghi dữ liệu nhị phân, bắt buộc phải mở file ở chế độ nhị phân (ở đây là chuyển "rb" sang open()). Nếu bạn sử dụng "r" thay thế (mặc định), tệp sẽ được mở ở chế độ văn bản và f.read() sẽ trả về các đối tượng str thay vì các đối tượng bytes.

Tôi dường như không thể sử dụng os.read() trên một đường dẫn được tạo bằng os.popen(); Tại sao?

os.read() là một hàm cấp thấp có bộ mô tả tệp, một số nguyên nhỏ biểu thị tệp đã mở. os.popen() tạo một đối tượng tệp cấp cao, cùng loại được trả về bởi hàm open() tích hợp. Do đó, để đọc byte n từ ống p được tạo bằng os.popen(), bạn cần sử dụng p.read(n).

Làm cách nào để truy cập vào cổng nối tiếp (RS232)?

Đối với Win32, OSX, Linux, BSD, Jython, IronPython:

Đối với Unix, hãy xem bài đăng trên Usenet của Mitch Chapman:

Tại sao việc đóng sys.stdout (stdin, stderr) không thực sự đóng nó?

Python file objects là lớp trừu tượng cấp cao trên các bộ mô tả tệp C cấp thấp.

Đối với hầu hết các đối tượng tệp bạn tạo bằng Python thông qua hàm open() tích hợp sẵn, f.close() đánh dấu đối tượng tệp Python là bị đóng theo quan điểm của Python và cũng sắp xếp để đóng bộ mô tả tệp C bên dưới. Điều này cũng tự động xảy ra trong hàm hủy của f khi f trở thành rác.

Nhưng stdin, stdout và stderr được Python xử lý đặc biệt, do trạng thái đặc biệt cũng được C cấp cho chúng. Chạy sys.stdout.close() đánh dấu đối tượng tệp cấp Python là bị đóng, nhưng not có đóng bộ mô tả tệp C liên quan hay không.

Để đóng bộ mô tả tệp C cơ bản cho một trong ba bộ mô tả này, trước tiên bạn phải chắc chắn rằng đó là điều bạn thực sự muốn làm (ví dụ: bạn có thể nhầm lẫn giữa các mô-đun mở rộng đang cố gắng thực hiện I/O). Nếu có, hãy sử dụng os.close():

os.close(stdin.fileno())
os.close(stdout.fileno())
os.close(stderr.fileno())

Hoặc bạn có thể sử dụng các hằng số 0, 1 và 2 tương ứng.

Lập trình mạng/Internet

Có những công cụ WWW nào dành cho Python?

Xem các chương có tiêu đề Giao thức và hỗ trợ InternetXử lý dữ liệu Internet trong Sổ tay tham khảo Thư viện. Python có nhiều mô-đun sẽ giúp bạn xây dựng hệ thống web phía máy chủ và phía máy khách.

Bản tóm tắt các khung có sẵn được duy trì bởi Paul Boddie tại https://wiki.python.org/moin/WebProgramming.

Tôi nên sử dụng mô-đun nào để trợ giúp tạo HTML?

Bạn có thể tìm thấy bộ sưu tập các liên kết hữu ích trên Web Programming wiki page.

Làm cách nào để gửi thư từ tập lệnh Python?

Sử dụng mô-đun thư viện tiêu chuẩn smtplib.

Đây là một trình gửi thư tương tác rất đơn giản sử dụng nó. Phương pháp này sẽ hoạt động trên bất kỳ máy chủ nào hỗ trợ trình nghe SMTP.

nhập sys, smtplib

fromaddr = đầu vào ("Từ:")
toaddrs = input("To:").split(',')
print("Nhập tin nhắn, kết thúc bằng ^D:")
tin nhắn = ''
trong khi Đúng:
    dòng = sys.stdin.readline()
    nếu không phải dòng:
        phá vỡ
    dòng tin nhắn +=

# The gửi thư thực tế
máy chủ = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
máy chủ.quit()

Một giải pháp thay thế chỉ dành cho Unix sử dụng sendmail. Vị trí của chương trình sendmail khác nhau giữa các hệ thống; đôi khi là /usr/lib/sendmail, đôi khi là /usr/sbin/sendmail. Trang hướng dẫn sử dụng sendmail sẽ giúp bạn. Đây là một số mã mẫu:

hệ điều hành nhập khẩu

SENDMAIL = "/usr/sbin/sendmail" vị trí # sendmail
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("Tới: người nhận@example.com\n")
p.write("Chủ đề: bài kiểm tra\n")
p.write("\n") # blank dòng tách các tiêu đề khỏi nội dung
p.write("Một số văn bản\n")
p.write("thêm một số văn bản\n")
sts = p.close()
nếu sts != 0:
    print("Trạng thái thoát Sendmail", sts)

Làm cách nào để tránh bị chặn trong phương thức connect() của ổ cắm?

Mô-đun select thường được sử dụng để hỗ trợ I/O không đồng bộ trên ổ cắm.

Để ngăn kết nối TCP bị chặn, bạn có thể đặt ổ cắm ở chế độ không chặn. Sau đó, khi bạn thực hiện connect(), bạn sẽ kết nối ngay lập tức (không chắc) hoặc nhận được một ngoại lệ chứa số lỗi là .errno. errno.EINPROGRESS cho biết kết nối đang được tiến hành nhưng chưa kết thúc. Các hệ điều hành khác nhau sẽ trả về các giá trị khác nhau, vì vậy bạn sẽ phải kiểm tra những gì được trả về trên hệ thống của mình.

Bạn có thể sử dụng phương pháp connect_ex() để tránh tạo ngoại lệ. Nó sẽ chỉ trả về giá trị errno. Để thăm dò ý kiến, bạn có thể gọi lại connect_ex() sau -- 0 hoặc errno.EISCONN cho biết rằng bạn đã kết nối -- hoặc bạn có thể chuyển ổ cắm này tới select.select() để kiểm tra xem nó có thể ghi được hay không.

Ghi chú

Mô-đun asyncio cung cấp thư viện không đồng bộ đơn luồng và đồng thời cho mục đích chung, có thể được sử dụng để viết mã mạng không chặn. Thư viện Twisted của bên thứ ba là một giải pháp thay thế phổ biến và giàu tính năng.

Cơ sở dữ liệu

Có giao diện nào cho các gói cơ sở dữ liệu bằng Python không?

Vâng.

Các giao diện cho các hàm băm dựa trên đĩa như DBMGDBM cũng được bao gồm trong Python tiêu chuẩn. Ngoài ra còn có mô-đun sqlite3, cung cấp cơ sở dữ liệu quan hệ dựa trên đĩa nhẹ.

Hỗ trợ cho hầu hết các cơ sở dữ liệu quan hệ có sẵn. Xem DatabaseProgramming wiki page để biết chi tiết.

Làm cách nào để bạn triển khai các đối tượng liên tục trong Python?

Mô-đun thư viện pickle giải quyết vấn đề này theo cách rất tổng quát (mặc dù bạn vẫn không thể lưu trữ những thứ như tệp đang mở, ổ cắm hoặc cửa sổ) và mô-đun thư viện shelve sử dụng dưa chua và (g)dbm để tạo ánh xạ liên tục chứa các đối tượng Python tùy ý.

Toán học và Số học

Làm cách nào để tạo số ngẫu nhiên trong Python?

Mô-đun tiêu chuẩn random triển khai trình tạo số ngẫu nhiên. Cách sử dụng rất đơn giản:

nhập khẩu ngẫu nhiên
ngẫu nhiên.random()

Điều này trả về một số dấu phẩy động ngẫu nhiên trong phạm vi [0, 1).

Ngoài ra còn có nhiều máy phát điện chuyên dụng khác trong mô-đun này, chẳng hạn như:

  • randrange(a, b) chọn một số nguyên trong phạm vi [a, b).

  • uniform(a, b) chọn số dấu phẩy động trong phạm vi [a, b).

  • normalvariate(mean, sdev) lấy mẫu phân phối chuẩn (Gaussian).

Một số hàm cấp cao hơn hoạt động trực tiếp trên các chuỗi, chẳng hạn như:

  • choice(S) chọn một phần tử ngẫu nhiên từ một chuỗi nhất định.

  • shuffle(L) xáo trộn danh sách tại chỗ, tức là hoán vị nó một cách ngẫu nhiên.

Ngoài ra còn có lớp Random mà bạn có thể khởi tạo để tạo nhiều trình tạo số ngẫu nhiên độc lập.