事倍功半是蠢蛋05:python开发日记
pip更换清华源镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip show pip
pycharm管理员模式打开可以规避poetry install时候的权限问题
ctrl + shift + v 获取剪贴板
20250409 进阶python
https://github.com/ateliershen/Python-100-Days-zh_TW/blob/master/Day01-15/09.面向对象进阶.md
双下划线开头方法外部类不能用 单下划线方法约定俗成 不建议用
__slots__用法
@property包装 getter/setter
文件流
临时文件
json模組主要有四個比較重要的函式,分別是:
dump - 將Python物件按照JSON格式序列化到檔案中
dumps - 將Python物件處理成JSON格式的字串
load - 將檔案中的JSON資料反序列化成物件
loads - 將字串的內容反序列化成Python物件
這裡出現了兩個概念,一個叫序列化,一個叫反序列化。自由的百科全書維基百科上對這兩個概念是這樣解釋的:“序列化(serialization)在計算機科學的資料處理中,是指將資料結構或物件狀態轉換為可以儲存或傳輸的形式,這樣在需要的時候能夠恢復到原先的狀態,而且透過序列化的資料重新獲取位元組時,可以利用這些位元組來產生原始物件的副本(複製)。與這個過程相反的動作,即從一系列位元組中提取資料結構的操作,就是反序列化(deserialization)”。
我一直没有系统性学习多线程。
def download_task(filename):
print('啟動下載程序,程序號[%d].' % getpid())
print('開始下載%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下載完成! 耗費了%d秒' % (filename, time_to_download))
def main():
start = time()
p1 = Process(target=download_task, args=('Python從入門到住院.pdf', ))
p1.start()
p2 = Process(target=download_task, args=('Peking Hot.avi', ))
p2.start()
p1.join()
p2.join()
end = time()
print('總共耗費了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
from multiprocessing import Process
from time import sleep
counter = 0
def sub_task(string):
global counter
while counter < 10:
print(string, end='', flush=True)
counter += 1
sleep(0.01)
def main():
Process(target=sub_task, args=('Ping', )).start()
Process(target=sub_task, args=('Pong', )).start()
if __name__ == '__main__':
main()
看起來沒毛病,但是最後的結果是Ping和Pong各輸出了10個,Why?當我們在程式中建立程序的時候,子程序複製了父程序及其所有的資料結構,每個子程序有自己獨立的記憶體空間,這也就意味著兩個子程序中各有一個counter變數,所以結果也就可想而知了。要解決這個問題比較簡單的辦法是使用multiprocessing模組中的Queue類,它是可以被多個程序共享的佇列,底層是透過管道和訊號量(semaphore)機制來實現的,有興趣的讀者可以自己嘗試一下。
import threading
import time
# 不使用锁的版本 - 会导致错误结果
def without_lock():
# 共享资源
counter = 0
def increment():
nonlocal counter
current = counter
time.sleep(0.001) # 模拟处理延迟
counter = current + 1
# 创建10个线程
threads = []
for _ in range(10):
t = threading.Thread(target=increment)
threads.append(t)
t.start()
# 等待所有线程结束
for t in threads:
t.join()
print(f"不使用锁的结果: {counter} (应该是10)")
# 使用锁的版本 - 得到正确结果
def with_lock():
# 共享资源
counter = 0
lock = threading.Lock()
def increment():
nonlocal counter
with lock: # 使用锁保护临界区
current = counter
time.sleep(0.001) # 模拟处理延迟
counter = current + 1
# 创建10个线程
threads = []
for _ in range(10):
t = threading.Thread(target=increment)
threads.append(t)
t.start()
# 等待所有线程结束
for t in threads:
t.join()
print(f"使用锁的结果: {counter} (正确为10)")
if __name__ == '__main__':
without_lock()
with_lock()
如何分析任务是IO密集型还是CPU密集型
| 特性 | IO密集型 | CPU密集型 |
|---|---|---|
| 主要瓶颈 | 等待输入/输出操作 | 计算处理能力 |
| 资源使用 | CPU大部分时间空闲 | CPU使用率高 |
| 适合并发方式 | 多线程/异步IO | 多进程 |
IO密集型任务特征:
频繁的文件操作(读/写文件)
网络请求和数据传输
数据库操作
用户输入等待
程序运行时CPU使用率低
任务耗时与数据量成比例
CPU密集型任务特征:
复杂数学计算(如加密、压缩)
图形/图像处理
科学计算和模拟
大规模数据处理
程序运行时CPU使用率高
任务耗时与计算复杂度成比例

浙公网安备 33010602011771号