我正在使用一個執行緒來運行我的代碼的一個功能,這是一個片段:
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for addresses in ipa_str_s:
futures.append(executor.submit(checking_connection, ip_address=addresses))
for future in concurrent.futures.as_completed(futures):
save_result = (future.result())
saving_statistics(save_result, saving)
該變數ipa_str_s有一個 IP 地址串列。
saving_statistics函式,它等待函式的每次呼叫給checking_connection我機會save the result。
呼叫函式saving_statistics:
def saving_statistics(save_result, saving):
with open(saving, 'a', encoding='utf-8') as csv_file:
csv_writer = csv.writer(csv_file, delimiter=';')
csv_writer.writerow(['IP-address', 'Packets_transmitted', 'Packets_received'])
csv_writer.writerow(save_result)
如果指定 mode a,則得到以下結果:
IP-address;Packets_transmitted;Packets_received
192.168.1.1;3;3
IP-address;Packets_transmitted;Packets_received;
192.168.1.2;3;0
IP-address;Packets_transmitted;Packets_received;
192.168.1.3;3;0
如果指定 mode w,則得到以下結果:
IP-address;Packets_transmitted;Packets_received
192.168.1.3;3;0
你能告訴我,我怎樣才能得到這樣的檔案的正常內容:
IP-address;Packets_transmitted;Packets_received
192.168.1.1;3;3
192.168.1.2;3;0
192.168.1.3;3;0
非常感謝!
uj5u.com熱心網友回復:
每次呼叫 save_statistics 函式時,您的函式都會寫入第一行 (IP-address;Packets_transmitted;Packets_recieved)。
我看到三個解決方案:
- 在別處打開檔案并寫入第一行,然后根據需要呼叫該函式。程式終止時關閉檔案。
- 第一次呼叫函式時有一個為 True 的變數,然后將其更改為 false。使用它來確定是否列印標題行
- 將 IP 地址保存在一個串列物件中,并在程式終止時將它們全部寫入。
根據您希望它運行多長時間會更改最佳選項。如果你打算讓它運行一段時間,我會做 1 并在你的 main() 末尾有一個 file.close(),或者你正在運行它。如果是少量專案,3 可能是最簡單的。2 將導致最少的代碼更改。
uj5u.com熱心網友回復:
我認為您的整個程序就像建立多個異步網路連接一樣簡單,然后將結果收集到 CSV 檔案中,并且此程序可能會在合理的時間內運行,并且不會重新啟動。如果是這樣,請不要附加。
就像 Loydms 所說,打開然后寫入然后關閉:
import csv
import random
import time
import concurrent.futures
def checking_connection(addr):
sleep_ms = random.randrange(50, 100) / 1000
time.sleep(sleep_ms)
pckts_in = random.randrange(500, 1000)
pckts_out = random.randrange(500, 1000)
return addr, pckts_in, pckts_out, sleep_ms
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for address in [f"192.168.1.{x}" for x in range(256)]:
futures.append(executor.submit(checking_connection, address))
with open("data.csv", "w", newline="") as f:
writer = csv.writer(f, delimiter=";")
writer.writerow(["IP_address", "Packets_transmitted", "Packets_received", "Sleep"])
for future in concurrent.futures.as_completed(futures):
writer.writerow(future.result())
當我運行該代碼時,我每次都會得到一個新的 CSV,其中包含一個標題和 256 行假 IP 統計資訊,大約需要 1.8 秒:
| IP_address | Packets_transmitted | Packets_received | Sleep |
|---------------|---------------------|------------------|-------|
| 192.168.1.94 | 879 | 933 | 0.063 |
| 192.168.1.245 | 846 | 577 | 0.079 |
| 192.168.1.144 | 555 | 656 | 0.099 |
| 192.168.1.127 | 659 | 936 | 0.06 |
| 192.168.1.43 | 706 | 740 | 0.091 |
...
如果您的程序花費了不合理的時間,或者有重新啟動,那么要么選擇一種日志記錄方法,要么使用 Python 的 SQLite3 模塊來創建一個小型資料庫并進行插入。
您可以在最終需要時從日志檔案或資料庫創建 CSV。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/494960.html
標籤:python-3.x CSV 线程池执行器 并发期货
