<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          小白也能掌握的Python部署應(yīng)用技術(shù)

          共 7871字,需瀏覽 16分鐘

           ·

          2022-03-04 13:35

          點(diǎn)擊關(guān)注“Python數(shù)據(jù)分析實(shí)例

          設(shè)為“置頂或星標(biāo)”,送達(dá)干貨不錯過!

          前言

          如何將你寫的Python程序發(fā)布給其他人用呢?

          今天分享一下非常簡單可行的方式發(fā)布 Python 應(yīng)用程序,發(fā)布后只需要通過計(jì)算機(jī)管理后臺啟停你的應(yīng)用程序,熟悉后可在其基礎(chǔ)上進(jìn)行功能拓展改進(jìn),是小白快速開發(fā)一個可用落地應(yīng)用的最佳選擇。本文將詳細(xì)介紹兩種方法將Python程序部署成windows服務(wù)。Python web應(yīng)用服務(wù)器部署不在此次討論之中。


          一、Python腳本部署成windows定時(shí)任務(wù)

          1) Outline_analysis.py腳本準(zhǔn)備

          主要實(shí)現(xiàn)數(shù)據(jù)在線定時(shí)反饋功能,函數(shù)執(zhí)行流主要分為3部分,tick1()函數(shù)實(shí)現(xiàn)數(shù)據(jù)提取生產(chǎn),tick2()函數(shù)實(shí)現(xiàn)發(fā)送報(bào)警郵件,end_program()函數(shù)實(shí)現(xiàn)關(guān)閉后臺python解釋器釋放資源,確保程序持續(xù)穩(wěn)定運(yùn)行。

          from?datetime?import?datetime
          import?time
          from?tools.sender_mail?import?Sender_mail
          from?tools.Wrapper_timer?import?time_logger
          now_time?=?datetime.now().date()

          #業(yè)務(wù)數(shù)據(jù)生產(chǎn)過程
          def?tick1():
          ????time.sleep(4)
          ????print('Tick!The?time?is:%s'?%?datetime.now())

          #預(yù)警信息發(fā)送
          def?tick2():
          ????#發(fā)送郵件
          ????Sender_mail.sender_mail()
          ????print('發(fā)送完成')


          #?def?get_pid(name):
          #?????'''
          #??????作用:根據(jù)進(jìn)程名獲取進(jìn)程pid
          #?????'''
          #?????import?psutil
          #?????pids?=?psutil.process_iter()
          #?????print("["?+?name?+?"]'s?pid?is:")
          #?????for?Pid?in?pids:
          #?????????if(Pid.name()?==?name):
          #?????????????P=Pid.pid
          #?????return?P

          #關(guān)閉解釋器
          def?end_program():
          ????#?pr_name?=?get_pid(name="pythonw.exe")
          ????#?os.system('%s%s'?%?("taskkill?/F?/PID?",pr_name))
          ????#os.system('%s%s'?%?("taskkill?/F?/IM?pythonw.exe"))
          ????
          ????import?subprocess
          ????CREATE_NO_WINDOW?=?0x08000000
          ????subprocess.call('taskkill?/F?/IM?pythonw.exe',?creationflags=CREATE_NO_WINDOW)

          #業(yè)務(wù)流程
          @time_logger
          def?tick():
          ????tick1()
          ????tick2()
          ????end_program()

          if?__name__?=='__main__':
          ????tick()

          注:

          1、業(yè)務(wù)數(shù)據(jù)生產(chǎn)過程--tick1()函數(shù)

          該函數(shù)用休眠模擬數(shù)據(jù)處理耗時(shí),實(shí)際應(yīng)用中連接生產(chǎn)數(shù)據(jù)庫,經(jīng)過一系列處理流程,本地開發(fā)數(shù)據(jù)庫Mysql,數(shù)據(jù)庫連接主機(jī)名寫的是localhost;如果項(xiàng)目部署到遠(yuǎn)程服務(wù)器上,數(shù)據(jù)庫和項(xiàng)目部署在不同機(jī)器上,數(shù)據(jù)庫連接的主機(jī)名就需要修改成數(shù)據(jù)庫所部署的那臺機(jī)器的公網(wǎng)ip或者域名,通過ipconfig查看。


          2、關(guān)閉python解釋器--end_program()函數(shù)

          • 調(diào)用taskkill命令,關(guān)閉指定的進(jìn)程

          詳細(xì)參數(shù)用法可網(wǎng)上搜索查看;常見用法TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T]

          • 窗口隱藏不顯示

          將腳本解析程序python.exe改為pythonw.exe.將不會彈出控制臺窗口。

          使用系統(tǒng)os.system()關(guān)閉解釋器程序?qū)⑵灵W退出,建議使用python調(diào)用cmd命令隱藏窗口方法subprocess.call(),將解決這個問題,詳細(xì)可參考--

          https://stackoverflow.com/questions/7006238/how-do-i-hide-the-console-when-i-use-os-system-or-subprocess-call

          3、數(shù)據(jù)管道流按順序執(zhí)行

          該處可利用多線程隊(duì)列實(shí)現(xiàn)數(shù)據(jù)流按順序執(zhí)行

          def?tick():
          ????print('job?thread_id-{0},?process_id-{1}'.format(threading.get_ident(),?os.getpid()))
          ????w?=?WorkerThread()
          ????w.start()
          ????w.send(tick1())
          ????w.send(tick2())
          ????w.run()
          ????w.send(end_program())
          ????w.run()
          ????w.close()


          #?使用?隊(duì)列一般可以簡化多線程的程序。例如,可以使用共享隊(duì)列將線程連接在一起,而不必依賴鎖的保護(hù)。
          #?在這種模型下,工作者線程一般充當(dāng)數(shù)據(jù)的消費(fèi)者。
          from?threading?import?Thread
          from?queue?import?Queue
          import?time,os,threading
          class?WorkerThread(Thread):
          ????def?__init__(self,*args,**kwargs):
          ????????Thread.__init__(self,*args,**kwargs)
          ????????self.input_queue=Queue()

          ????def?send(self,item):
          ????????self.input_queue.put(item)

          ????def?close(self):
          ????????self.input_queue.put(None)
          ????????self.input_queue.join()
          ????def?run(self):
          ????????while?True:
          ????????????item=self.input_queue.get()
          ????????????if?item?is?None:
          ????????????????break
          ????????????#實(shí)際開發(fā)中,此處應(yīng)該使用有用的工作代替
          ????????????print(item)
          ????????????self.input_queue.task_done()
          ????????#完成,指示收到和返回哨兵
          ????????self.input_queue.task_done()
          ????????return



          4、后期優(yōu)化細(xì)節(jié)

          tools文件夾下存放Sender_mail、time_logger等拓展模塊。個執(zhí)行任務(wù)函數(shù)都可能失敗,因此可用加入裝飾器拓展函數(shù)功能,增加計(jì)時(shí)、日志記錄等,比如一個任務(wù)不確定什么時(shí)間完成,可設(shè)置超時(shí)時(shí)間,如果超時(shí)仍然未完成可用通過控制超時(shí)重新運(yùn)行,也可以設(shè)置重試次數(shù),超過一定次數(shù)報(bào)錯退出。

          import?functools
          import?logging
          import?time
          from?datetime?import?datetime

          log_format?=?"%(asctime)s?%(message)s"
          logging.basicConfig(format=log_format,
          ????????????????????level=logging.INFO,
          ????????????????????datefmt="?%Y-%m-%d?%H:%M:%S",??#?時(shí)間格式
          ????????????????????filename="log1.log",
          ????????????????????filemode="a")


          #?裝飾器會被任何函數(shù)使用。其中的func(*args, **kwargs)中的func就是目標(biāo)函數(shù),args、kwargs是這個函數(shù)調(diào)用的參數(shù)
          def?time_logger(func):
          [email protected](func)
          ??def?wrapper_timer(*args,?**kwargs):
          ????logging.info(f"BeginFunction?{func.__name__!r},?args={args},?kwargs={kwargs}")
          ????start_time?=?time.perf_counter()??#?1
          ????value?=?func(*args,?**kwargs)
          ????end_time?=?time.perf_counter()??#?2
          ????run_time?=?end_time?-?start_time??#?3

          ????logging.info(f"EndFunction?{func.__name__!r}?in?{run_time:.4f}?secs")
          ????return?value,run_time

          ??return?wrapper_timer



          2)將腳本設(shè)置成windows定時(shí)任務(wù)

          首先搜索框-計(jì)算機(jī)管理-點(diǎn)擊任務(wù)計(jì)劃程序庫-可查看已有的定時(shí)計(jì)劃任務(wù)

          點(diǎn)擊創(chuàng)建任務(wù)進(jìn)入按提示設(shè)置即可


          常規(guī)設(shè)置,名稱、用戶設(shè)置,更改用戶或組注意用戶權(quán)限設(shè)置

          接下來,設(shè)置觸發(fā)器,定時(shí)任務(wù)開始運(yùn)行觸發(fā)條件,根據(jù)需要設(shè)置

          最關(guān)鍵的一步,設(shè)置python解釋器位置及執(zhí)行腳本路徑

          電腦休眠狀態(tài)定時(shí)任務(wù)不會執(zhí)行,需要勾選喚醒計(jì)算機(jī)執(zhí)行該任務(wù)


          最后,啟用該定時(shí)任務(wù),確保單個實(shí)例執(zhí)行



          Windows 10定時(shí)任務(wù)運(yùn)行報(bào)錯:操作員或系統(tǒng)管理員拒絕了請求的解決方法

          解決辦法:首先確保python解釋器在進(jìn)程列表中退出,打開控制面板->管理工具->本地安全策略,選擇安全設(shè)置->本地策略->安全選項(xiàng),在右邊列表中找到域控制器:允許服務(wù)器操作者計(jì)劃任務(wù),將狀態(tài)改為已啟用。其次,用戶權(quán)限分配設(shè)置問題及環(huán)境變量配置。

          二、Python的exe執(zhí)行文件部署成windows服務(wù)

          1)Outline_analysis.exe腳本準(zhǔn)備

          from?datetime?import?datetime
          import?time,os,threading
          from?tools.Wrapper_timer?import?time_logger
          from?apscheduler.schedulers.blocking?import?BlockingScheduler
          from?apscheduler.executors.pool?import?ThreadPoolExecutor
          from?tools.Queue_thread?import?WorkerThread
          import?logging

          now_time?=?datetime.now().date()
          #?業(yè)務(wù)數(shù)據(jù)生產(chǎn)過程
          @time_logger
          def?tick1():
          ????print('job1?thread_id-{0},?process_id-{1}'.format(threading.get_ident(),?os.getpid()))
          ????time.sleep(1)
          ????print('Tick!The?time?is:%s'?%?datetime.now())


          #?預(yù)警信息發(fā)送
          @time_logger
          def?tick2():
          ????print('job2?thread_id-{0},?process_id-{1}'.format(threading.get_ident(),?os.getpid()))
          ????#?發(fā)送郵件
          ????time.sleep(1)
          ????print('郵件發(fā)送完成?%s'%?datetime.now())

          #數(shù)據(jù)存儲
          @time_logger
          def?tick3():
          ????print('job3?thread_id-{0},?process_id-{1}'.format(threading.get_ident(),?os.getpid()))
          ????#?數(shù)據(jù)存儲
          ????time.sleep(1)
          ????print('存儲完成?%s'%?datetime.now())


          def?tick():
          ????print('job?thread_id-{0},?process_id-{1}'.format(threading.get_ident(),?os.getpid()))
          ????w?=?WorkerThread()
          ????w.start()
          ????w.send(tick1())
          ????w.send(tick2())
          ????w.run()
          ????w.send(tick3())
          ????w.run()
          ????w.close()

          if?__name__?==?'__main__':
          ????executors?=?{
          ????????'default':?ThreadPoolExecutor(10)
          ????}
          ????scheduler?=?BlockingScheduler(executors=executors,)
          ????#?scheduler.add_job(tick,max_instances=5,trigger='interval',?seconds=10,id='interval_task')
          ????#注意裝飾器@time_logger不能放在tick前面,否則會出現(xiàn)阻塞,程序無法繼續(xù)運(yùn)行
          ????scheduler.add_job(tick,max_instances=5,trigger='interval',?seconds=10)
          ????#?run_time=tick1()[1]
          ????#?print("完成時(shí)間",run_time)
          ????#?scheduler._logger=logging
          ????try:
          ????????scheduler.start()
          ????except?(KeyboardInterrupt,SystemExit):
          ????????pass

          exe部署與py腳本部署不同:py腳本運(yùn)行不需要在代碼中設(shè)置時(shí)間控制邏輯,在定時(shí)任務(wù)設(shè)置運(yùn)行時(shí)間計(jì)劃,而exe部署需要將定時(shí)運(yùn)行代碼寫入腳本后打包。當(dāng)然,你也可以在編輯器中運(yùn)行程序,確保程序不會被關(guān)閉或者設(shè)置定時(shí)任務(wù)控制服務(wù)的開啟關(guān)閉。

          bug解決:max_instances默認(rèn)值為1,它表示id相同的任務(wù)實(shí)例數(shù);通過設(shè)置max_instances參數(shù)。裝飾器不要放在主線程tick()上面即可。

          • 打包:進(jìn)入項(xiàng)目目錄,激活虛擬環(huán)境,切換到python基本所在文件夾位置,輸入:“pyinstaller -F -w *.py” 就可以制作出exe。生成的文件放在同目錄dist下。-F(注意大寫)是所有庫文件打包成一個exe,-w是不出控制臺窗口。

          • 打包錯誤問題定位-cmd路徑下執(zhí)行Outline_analysis.exe,通過查看運(yùn)行輸出代碼運(yùn)行print信息:比如python使用pyinstaller打包成exe報(bào)Faild to execute script 解決,這個問題出現(xiàn)的原因是,有些模塊是隱藏導(dǎo)入的,但是pyinstaller打包時(shí)并未指定,所以執(zhí)行時(shí)找不到此模塊。其他錯誤可按提示百度、谷歌、GitHub 和 StackOverflow四件套解決。

          2)將exe執(zhí)行文件部署成windows服務(wù)

          • 使用windows自帶的命令sc 使用sc create 方法創(chuàng)建。

            這種方法不一定能成功,如果你的exe不符合服務(wù)的規(guī)范,可能會啟動失敗

          • 在第一種方法失敗的情況下,們可以在官網(wǎng)下載instsrv.exe 和 srvany.exe 兩個小工具注冊服務(wù)。

          1、下載后放入C盤下創(chuàng)建的一個文件夾以管理員的身份運(yùn)行命令行,首先進(jìn)入工具所在的文件夾。具體操作如下:

          執(zhí)行命令 instsrv.exe 你的服務(wù)名稱 srvany.exe文件路徑

          2、啟動注冊表:win+r——regedit打開注冊表路徑:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\OnlineServer

          3、找到剛注冊的服務(wù)名稱

          新建項(xiàng):Parameters

          在Parameters下新建字符串值:

          名稱為:Application 值: exe 所在的全路徑 包含exe名稱為:Application 值: exe 所在的全路徑 包含exe在Parameters下新建字符串值:名稱為:AppDirectory 值: exe 所在的路徑

          4、打開服務(wù),找到剛才所創(chuàng)建的服務(wù)名稱,配置屬性,點(diǎn)擊啟動

          5、刪除服務(wù),先將服務(wù)停止cd 到instsrv.exe 所在目錄 然后執(zhí)行instsrv.exe OnlineServer remove

          補(bǔ)救措施

          如果加入定時(shí)任務(wù)模塊apscheduler打包失敗的話,可以通過以下方式實(shí)現(xiàn)服務(wù)定時(shí)啟動。

          1、創(chuàng)建bat快捷方式,然后右鍵快捷方式-->properties-->advanced-->Run as administrator。
          2、下載bat轉(zhuǎn)成exe工具,將bat轉(zhuǎn)成exe,然后右鍵exe-->properties-->Compatibility-->Run as administrator。

          給大家分享一個windows的批處理文件(.bat文件)轉(zhuǎn)exe可執(zhí)行文件的工具。使用非常簡單,輸入需要轉(zhuǎn)換的腳本語句,點(diǎn)擊轉(zhuǎn)換即可。

          StartServers.bat文件

          net stop OnlineServers 停止服務(wù)

          net start OnlineServers 重啟服務(wù)

          以上工具獲取見文末

          將生成的restart設(shè)置成定時(shí)任務(wù),設(shè)置方法見上文。

          通過以上流程設(shè)置,一個簡單可用的腳本程序部署完畢,靜靜的在后臺運(yùn)行為你服務(wù)。當(dāng)然,簡單的應(yīng)用可以通過以上方式簡單部署,復(fù)雜的大型項(xiàng)目還是得上部署框架啦!

          Python 項(xiàng)目開發(fā)部署與發(fā)布一般流程如下:

          1、環(huán)境配置

          (1)開發(fā)環(huán)境Python 版本、anaconda環(huán)境、 pip 安裝 Python 依賴等

          (2)虛擬環(huán)境搭建,用 pipenv 安裝 項(xiàng)目的Python 依賴

          (3)安裝IDE如Pycharm編輯器

          (4)數(shù)據(jù)庫的部署等

          2、測試環(huán)境測試

          3、配置服務(wù),部署到生產(chǎn)環(huán)境,并發(fā)布應(yīng)用

          趕快上手部署一波,給你小伙伴每日郵箱轟炸、定時(shí)關(guān)心!哈哈

          后臺回復(fù)注冊服務(wù)小工具獲取

          瀏覽 84
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲成人天堂 | 精品人妻免费视频 | 一级毛片电影 | 国内免费毛片一区二区 | 日韩人成|