python文件打包生成可执行文件exe

2022-08-20 13:55:22

python文件打包成exe可执行文件:

以game2048.py脚本为例,实现打包生成可执行文件

非计算机软件专业的我从大学开始学习计算机语言后,只知道如何写代码,运行调试,功能实现,总感觉差丢丢儿。后来因为兴趣和工作需要,每每写好一个算法或功能,我只能把源代码拿出去展示?莫名感觉没有档次,总感觉缺一丢丢。写了训练人工智能识别算法智能在cmd或IDE上面弄。换台电脑做算法就心累,环境布置,库安装要削减发量的有木有。所以,自己做不限制环境的工具非常有必要,而且发给朋友同事做数据处理超级适用。本文介绍将python文件打包成exe可执行文件的方法。


关键库:

提示:pyinstaller安装,使用实践。

1、 安装pyinstaller
anaconda大环境下安装运行:conda install pyinstaller
没有conda就在命令行中运行:pip install pyinstaller

2、 打包python文件实例
将编写的2048游戏程序脚本保存在game2048.py中;
把它打包成exe需要在同一文件夹中打开命令行并输入:
pyinstaller -F ./game2048.py
回车后运行,如果一切顺利,文件夹中会多出一个后缀为spec的文件,以及两个名为dist和build的文件夹。
打开dist,可以找到game2048.exe,这就是生成的可执行文件。

3、pyinstaller的其他的选项,参数:
-i: 后接图标文件名,表示用自定义图标生成exe程序
-w: 生成的exe程序不带窗口执行
如果想只运行tkinter 页面,去掉dos窗口需要在打包的时候 加上 -w 参数

eg. pyinstaller -F calc.py -w

注意:

  1. pyinstaller需安装在脚本所依赖环境env里,或者打包时保证你的脚本运行和所依赖的env一致。比如,用命令行打包有默认python环境,而调试代码用的是另一个环境。

  2. 生成的exe文件可复制到电脑上的任何地方单独使用。


实践:

游戏脚本game2048.py
注意:游戏界面引入了curses库,Windows下使用该库的注意事项和安装

# !/usr/bin/env python# -*- coding: utf-8 -*-# @Time    : 2021/8/6 15:15# @Author  : Haiyan T# @Email   : 893190391@qq.com# @File    : game2048.py# Begin to show your code!import curses# 绘制在下的用户界面和漂亮的图形from randomimport randrange, choicefrom collectionsimport defaultdict

letter_codes=[ord(ch)for chin'WASDRQwasdrq']# 上左下右,ord函数是把字符转换成对应的数字
actions=['Up','Left','Down','Right','Restart','Exit']# 上,左,下,右,重启,退出
actions_dict=dict(zip(letter_codes, actions*2))# 把字母与动作对应起来。 zip是把元组中的值对应起来。# print(actions_dict)defget_user_action(keyboard):
    char="N"# char的初始值为Nwhile charnotin actions_dict:
        char= keyboard.getch()return actions_dict[char]# 阻塞+循环,直到获得用户有效输入才返回对应行为# 行列转置deftranspose(field):return[list(row)for rowinzip(*field)]# zip函数里边加*号,是把行变列,列变行。# 列表前后颠倒definvert(field):return[row[::-1]for rowin field]# 创建棋盘classGameField(object):def__init__(self, height=4, width=4, win=2048):
        self.height= height# 高
        self.width= width# 宽
        self.win_value= win# 过关分数
        self.score=0# 当前分数
        self.highscore=0# 最高分
        self.reset()# 重置棋盘defreset(self):# 定义一个reset函数if self.score> self.highscore:# 如果当前分数大于最高分,那么把当前分数赋值给最高分
            self.highscore= self.score
        self.score=0# 当前分数恢复到0分
        self.field=[[0for iinrange(self.width)]for jinrange(self.height)]# 横纵坐标恢复到(0,0)
        self.spawn()# 调用spawn这个函数
        self.spawn()defmove(self, direction):# 定义move函数defmove_row_left(row):# 向左移deftighten(row):# squeese non-zero elements together 把零散的非零单元挤到一块
                new_row=[ifor iin rowif i!=0]# 如果i不等于零,把他们赋值到new_row这个元组中
                new_row+=[0for iinrange(len(row)-len(new_row))]# 其余位置用0补充return new_row# 返回这个元组defmerge(row):# 定义merge函数,用来合并单元
                pair=False# pair初始值为假
                new_row=[]# new_row初始值为空for iinrange(len(row)):# 让i在格子里循环if pair:# 如果pair为真
                        new_row.append(2* row[i])# 那么把把row【i】的值乘以2,追加到new_row后边
                        self.score+=2* row[i]# 并且得分为row【i】的值乘以2
                        pair=False# pair重新赋值为假else:# 如果pair为真if i+1<len(row)and row[i]== row[i+1]:# 如果i+1还没到边界,并且此时的row【i】=row【i+1】
                            pair=True# 那么pair为真
                            new_row.append(0)# new_row后追加零else:
                            new_row.append(row[i])# 否则追加row【i】assertlen(new_row)==len(row)# 提醒两者长度一致return new_rowreturn tighten(merge(tighten(row)))# 反复合并,知道不能合并为止

        moves={}
        moves['Left']=lambda field:                              \[move_row_left(row)for rowin field]# 做移动
        moves['Right']=lambda field:                              \
                invert(moves['Left'](invert(field)))# invert是逆转
        moves['Up']=lambda field:                              \
                transpose(moves['Left'](transpose(field)))# transpose是转置
        moves['Down']=lambda field:                              \
                transpose(moves['Right'](transpose(field)))if directionin moves:if self.move_is_possible(direction):# 如果移动方向在四个方向上,
                self.field= moves[direction](self.field)# 那么调用moves函数
                self.spawn()# 产生随机数returnTrueelse:returnFalsedefis_win(self):returnany(any(i>= self.win_valuefor iin row)for rowin self.field)defis_gameover(self):returnnotany(self.move_is_possible(move)for movein actions)defdraw(self, screen):
        help_string1='(W)Up (S)Down (A)Left (D)Right'
        help_string2='     (R)Restart (Q)Exit'
        gameover_string='           GAME OVER'
        win_string='          YOU WIN!'defcast(string):
            screen.addstr(string+'\n')defdraw_hor_separator():
            line='+'+('+------'* self.width+'+')[1:]
            separator= defaultdict(lambda: line)ifnothasattr(draw_hor_separator,"counter"):
                draw_hor_separator.counter=0
            cast(separator[draw_hor_separator.counter])
            draw_hor_separator.counter+=1defdraw_row(row):
            cast(''.join('|{: ^5} '.format(num)if num>0else'|      'for numin row)+'|')

        screen.clear()
        cast('SCORE: '+str(self.score))if0!= self.highscore:
            cast('HGHSCORE: '+str(self.highscore))for rowin self.field:
            draw_hor_separator()
            draw_row(row)
        draw_hor_separator()if self.is_win():
            cast(win_string)else:if self.is_gameover():
                cast(gameover_string)else:
                cast(help_string1)
        cast(help_string2)defspawn(self):
        new_element=4if randrange(100)>89else2(i, j)= choice([(i, j)for iinrange(self.width)for jinrange(self.height)if self.field[i][j]==0])
        self.field[i][j]= new_elementdefmove_is_possible(self, direction):defrow_is_left_movable(row):defchange(i):# true if there'll be change in i-th tileif row[i]==0and row[i+1]!=0:# MovereturnTrueif row[i]!=0and row[i+1]== row[i]:# MergereturnTruereturnFalsereturnany(change(i)for iinrange(len(row)-1))

        check={}
        check['Left']=lambda field:                              \any(row_is_left_movable(row)for rowin field)

        check['Right']=lambda field:                              \
                 check['Left'](invert(field))

        check['Up']=lambda field:                              \
                check['Left'](transpose(field))

        check['Down']=lambda field:                              \
                check['Right'](transpose(field))if directionin check:return check[direction](self.field)else:returnFalsedefmain(stdscr):definit():# 重置游戏棋盘
        game_field.reset()return'Game'defnot_game(state):# 画出 GameOver 或者 Win 的界面
        game_field.draw(stdscr)# 读取用户输入得到action,判断是重启游戏还是结束游戏
        action= get_user_action(stdscr)
        responses= defaultdict(lambda: state)# 默认是当前状态,没有行为就会一直在当前界面循环
        responses['Restart'], responses['Exit']='Init','Exit'# 对应不同的行为转换到不同的状态return responses[action]defgame():# 画出当前棋盘状态
        game_field.draw(stdscr)# 读取用户输入得到action
        action= get_user_action(stdscr)if action=='Restart':return'Init'if action=='Exit':return'Exit'if game_field.move(action):# move successfulif game_field.is_win():return'Win'if game_field.is_gameover():return'Gameover'return'Game'

    state_actions={'Init': init,'Win':lambda: not_game('Win'),'Gameover':lambda: not_game('Gameover'),'Game': game}

    curses.use_default_colors()
    game_field= GameField(win=2048)

    state='Init'# 状态机开始循环while state!='Exit':
        state= state_actions[state]()


curses.wrapper(main)

anaconda prompt下运行打包:
(DeepLearningSlideCaptcha) C:\Users\Administrator>pyinstaller -F E:\structure_learning\0304t\2048\game2048.py

  1. (DeepLearningSlideCaptcha) 环境,可使用activate切换。
  2. pyinstaller -F E:\structure_learning\0304t\2048\game2048.py 命令。
  3. 结果
......7280 INFO: checking EXE7281 INFO: Building EXE because EXE-00.tocis non existent7281 INFO: Building EXEfrom EXE-00.toc7281 INFO: Appending archive to EXE C:\Users\Administrator\dist\game2048.exe7286 INFO: Building EXEfrom EXE-00.toc completed successfully.

测试:

  1. 直接打包

生成的exe程序如下:
在这里插入图片描述
双击运行
在这里插入图片描述
2. 带图标打包
pyinstaller -F -i 图标地址 脚本地址
回车,打包完成

pyinstaller-F-i E:\TanhaiyanLearn\structure_learning\0304t\2048\2048.ico  E:\TanhaiyanLearn\structure_learning\0304t\2048\game2048.pyE:\TanhaiyanLearn\structure_learning\0304t\2048\2048.ico  E:\TanhaiyanLearn\structure_learning\0304t\2048\game2048.py

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 作者:柏常青
  • 原文链接:https://blog.csdn.net/beauthy/article/details/119459813
    更新时间:2022-08-20 13:55:22