1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

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

        共 7871字,需瀏覽 16分鐘

         ·

        2022-03-04 13:35

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

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

        前言

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

        今天分享一下非常簡(jiǎn)單可行的方式發(fā)布 Python 應(yīng)用程序,發(fā)布后只需要通過(guò)計(jì)算機(jī)管理后臺(tái)啟停你的應(yīng)用程序,熟悉后可在其基礎(chǔ)上進(jìn)行功能拓展改進(jìn),是小白快速開(kāi)發(fā)一個(gè)可用落地應(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)閉后臺(tái)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)過(guò)程
        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)過(guò)程--tick1()函數(shù)

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


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

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

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

        • 窗口隱藏不顯示

        將腳本解析程序python.exe改為pythonw.exe.將不會(huì)彈出控制臺(tái)窗口。

        使用系統(tǒng)os.system()關(guān)閉解釋器程序?qū)⑵灵W退出,建議使用python調(diào)用cmd命令隱藏窗口方法subprocess.call(),將解決這個(gè)問(wèn)題,詳細(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ì)列一般可以簡(jiǎn)化多線程的程序。例如,可以使用共享隊(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í)際開(kāi)發(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等拓展模塊。個(gè)執(zhí)行任務(wù)函數(shù)都可能失敗,因此可用加入裝飾器拓展函數(shù)功能,增加計(jì)時(shí)、日志記錄等,比如一個(gè)任務(wù)不確定什么時(shí)間完成,可設(shè)置超時(shí)時(shí)間,如果超時(shí)仍然未完成可用通過(guò)控制超時(shí)重新運(yùn)行,也可以設(shè)置重試次數(shù),超過(guò)一定次數(shù)報(bào)錯(cuò)退出。

        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")


        #?裝飾器會(huì)被任何函數(shù)使用。其中的func(*args, **kwargs)中的func就是目標(biāo)函數(shù),args、kwargs是這個(gè)函數(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ì)劃程序庫(kù)-可查看已有的定時(shí)計(jì)劃任務(wù)

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


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

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

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

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


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



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

        解決辦法:首先確保python解釋器在進(jìn)程列表中退出,打開(kāi)控制面板->管理工具->本地安全策略,選擇安全設(shè)置->本地策略->安全選項(xiàng),在右邊列表中找到域控制器:允許服務(wù)器操作者計(jì)劃任務(wù),將狀態(tài)改為已啟用。其次,用戶權(quán)限分配設(shè)置問(wèn)題及環(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)過(guò)程
        @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ù)存儲(chǔ)
        @time_logger
        def?tick3():
        ????print('job3?thread_id-{0},?process_id-{1}'.format(threading.get_ident(),?os.getpid()))
        ????#?數(shù)據(jù)存儲(chǔ)
        ????time.sleep(1)
        ????print('存儲(chǔ)完成?%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前面,否則會(huì)出現(xiàn)阻塞,程序無(wú)法繼續(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)行程序,確保程序不會(huì)被關(guān)閉或者設(shè)置定時(shí)任務(wù)控制服務(wù)的開(kāi)啟關(guān)閉。

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

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

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

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

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

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

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

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

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

        2、啟動(dòng)注冊(cè)表:win+r——regedit打開(kāi)注冊(cè)表路徑:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\OnlineServer

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

        新建項(xiàng):Parameters

        在Parameters下新建字符串值:

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

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

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

        補(bǔ)救措施

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

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

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

        StartServers.bat文件

        net stop OnlineServers 停止服務(wù)

        net start OnlineServers 重啟服務(wù)

        以上工具獲取見(jiàn)文末

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

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

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

        1、環(huán)境配置

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

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

        (3)安裝IDE如Pycharm編輯器

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

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

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

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

        后臺(tái)回復(fù)注冊(cè)服務(wù)小工具獲取

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

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲妇女下面毛茸茸 | 野外被三个男人躁一夜漫画 | 打屁股play扇肿撅高羞耻h | 口述被爽到呻吟高潮自述 | 国产传媒福利 | 在线亚洲成人视频 | 欧美日韩精品一区二区三区 | 国产精品成人一区二区网站软件 | 成人影片大香蕉 | 天天爱天天干天天爽 |