分享

python创建可以打开文件的EXE

 意得tr6ekb6q8k 2017-11-24

首先抛出一个要解决的问题,在学python时用jupyter notebook记了很多笔记,而实际操作时有一些细节不记得了,需要查看笔记。但是一个.ipynb文件用文本编辑器打开,多了很多我们不想看到的文本,而用jupyter打开又很慢。于是需要设置出一个可执行程序exe文件)来打开.ipynb文件。

本文展示了一步步学习如何创建.exe程序的过程,最后做出我们想要的程序

本文分为如下几个内容

  • 生成最简单的exe程序,只打印出一段字符串

  • 带有参数的exe程序

  • 参数是文件名的情况

  • 真正实现

  • 改进方向

生成最简单的exe程序

将python脚本转化为exe程序比较常用的是两个库,py2exe和pyinstaller,由于前者不支持3.5及以上版本,操作也相对复杂,因此这里选择pyinstaller。

安装:在cmd中直接pip install PyInstaller 就安装好了。

之后我们只要使用pyinstaller这条命令即可,正常来说我们安装好这个库之后,pyinstaller.exe就在环境变量中了,所以我们可以在任何文件夹下的cmd窗口中调用这条命令。

pyinstaller库生成exe文件非常简单,只要一条命令就能自动生成,我们来看一下下面这个简单例子

在cmd_try文件夹下创建hello.py文件,文件中的内容如下

i = input('please input your name: ') print('Hello World '+i+'!')
# 注意:py2中的raw_input在py3中改成了input
# 用input而不是只是print是为了防止到时候调用exe程序时窗口一闪而过

然后我们在cmd_try文件夹下打开命令窗口,输入 pyinstaller hello.py 就会自动生成几个文件夹,dist文件夹中的hello文件夹中,就有了hello.exe文件,双击这个文件就会弹出一个让你输入名字的窗口,这就代表这个可执行程序创建完成。

注:同时会生成一个build文件,其中也有一个hello.exe,不用管它,把build文件夹删掉,dist中的hello.exe文件依然可以运行

如果要继续修改程序,修改后的hello.py保存后,要再用pyinstaller hello.py这条命令重新生成,覆盖原有的文件,hello.exe才能执行新的功能。

下面我们在命令行中调用这个可执行程序

在之前的命令行窗口中输入 cd dist 进入dist文件夹中,再输入 cd hello 进入hello文件夹中,再输入两种命令都可以:

  • 直接输入hello即调用了hello.exe文件,会在当前这个命令窗口中让你输入你的名字

  • 输入 start hello 则会另外出现一个命令窗口让你输入你的名字

  • 其中第一种其实和在cmd_try文件夹下的命令行窗口中输入python hello.py效果相同,所以我们可以用这个来测试,测试结束后再生成exe文件

带有参数的exe程序

因为我们的exe程序需要能够打开一个文件,所以需要调用外部参数。下面我们实现在命令行调用hello.py文件时传入参数。这里使用python内置的命令行解析库argparse,这个库的官网特别详细,一步一步教你如何操作,有兴趣的读者可以直接去官网学习,这里仅仅做最简单的使用。

hello.py文件中内容改为

import argparse parser = argparse.ArgumentParser parser.add_argument('name', help='input your name') # 添加 name 参数,并指定help信息args = parser.parse_args # 让args这个变量可以引用这个参数print('Hello World '+ args.name +'!') # 用args.name引用命令行中输入的参数

我们先直接用python来调用,在cmd_try目录下的cmd窗口输入 python hello.py 'bob' ,我们想要的结果就会在下面被打印出来

注:因为刚刚我们用cd命令把命令行窗口的位置切换到了hello文件夹下,如果想返回 cmd_try 文件夹下,则输入两次 cd .. 即可

接下来我们将程序打打包成exe文件,输入pyinstaller hello.py

cd到hello文件夹下输入hello 'bob'也可以打印出正常的结果

参数是文件名

为了和我们的目标更接近一点,我们现在实现提取一个txt文件中的内容,前后加一个html的标签,再存成一个html文件

hello.py文件换为如下内容

import argparse parser = argparse.ArgumentParser parser.add_argument('file', help='input your filename') # 添加 file 参数,并指定help信息args = parser.parse_args # 让args这个变量可以引用这个参数with open(args.file, 'r') as f: r = f.read html = '' + r + ''with open('a.html', 'w') as f: f.write(html)

同时在cmd_try文件夹中创建hi.txt文件,内容如下

Hi world! Hello world!

在cmd_try文件夹下的cmd窗口中输入 python hello.py 'hi.txt' 发现执行成功,在cmd_try文件夹下生成了一个a.html文件,我们可以双击这个文件则自动用浏览器打开,内容也是我们刚刚指定的内容。

于是我们再执行pyinstaller hello.py转化为exe程序。同时删除刚刚生成的a.html文件。

在hello文件夹下的cmd窗口中输入 hello C:\python\cmd_try\hi.txt(具体更改为读者电脑中hi.txt文件所在路径) 则会在hello文件夹下生成a.html

删除a.html文件,我们再换一种方式运行

右键hi.txt,选择打开方式-选择其他应用-更多应用-在这台电脑上查找其他应用,然后找到hello.exe的位置,勾选上“始终用此程序打开”,点击打开。这次没反应,但是下次你双击这个文件,就会在cmd_try文件夹下产生一个a.html文件,即运行成功。必须要设置默认用这个程序打开该类型文件,因为用这个过程选打开是没有效果的,只有双击打开才可以。双击打开就相当于用hello.exe调用这个文件作为参数,也就是之前我们在命令行中输入的执行代码。

到现在就万事具备了,接下来我们只要把试验的代码换成处理.ipynb文件的就可以了

真正实现

用文本编辑器打开.ipynb文件发现,它是一个json格式的文本数据,因此我们可以直接读取,转化为字典列表,再进行提取、添加标签即可生成网页源代码,再写出来成一个html文件即可。

因为主要是查看代码,所以这里只提取标题和代码,文本不予提取。标题会汇总在一起放在前面构成目录链接。

在my_project文件夹下建立一个ipynb_view.py文件,里面内容如下

import re
import json
import argparse
def view_ipynb_html(path_ipy, newname): # 传入要打开的文件路径,和新生成的文件名称 # path_ipy 是.ipynb文件及所在路径 with open(path_ipy, 'r', encoding='utf-8') as f: a = f.read # 读取得到的是一个json格式的字符串 b = json.loads(a) # 转化为字典格式便于处理 css = 'style type='text/css'>\nul li{list-style: none;}\na {text-decoration: none}style>' # 添加css样式,让目录简单一点 s = '\n' + css + '\n i want to replace here \n' # 创建一个字符串变量,之后所有内容往上面加,组成一个完整的html代码 contents = '
    \n'
# 目录的html代码,之后替换上面的 i want to replace here for d in b['cells']:
if d['cell_type'] == 'raw' or d['cell_type'] == 'code': # 提取代码 s += 'xmp>' + '\n' # 这个标签可以把里面的内容原样输出 for i in d['source']: s += i.rstrip + '\n' s += 'xmp>
\n'
elif d['cell_type'] == 'markdown': # 提取标题 result = re.findall('#+ .+',d['source'][0])
if result: n = result[0].count('#') # 查看几级标题 result1 = re.sub('#+ ''',result[0]) s += '<> + str(n) + ' id='' + result1 +''>' + result1 + ' + str(n) + '>' + '\n' contents += '
  • + result1 + '' target=''>' + ' '*(n-1)*4 + result1 + '\n' s += '\n' contents += '' s = s.replace('i want to replace here',contents)
    with open(newname, 'w') as f: f.write(s)# 命令行解析,以文件及其路径作为文件的参数

    parser = argparse.ArgumentParser parser.add_argument('file', help='input your filename') # 添加 file 参数,并指定help信息args = parser.parse_args # 让args这个变量可以引用file这个参数

    # 提取新文件名oriname = re.search('\\\\(\w*?\.ipynb)',args.file).group(1) newname = oriname.replace('ipynb''html')# 调用函数创建文件

    view_ipynb_html(args.file,newname)

    文件写好保存之后,在ipynb_view文件夹下打开命令行窗口,输入 python ipynb_view.py C:\Jupyter\base.ipynb (路径改为读者自己的.ipynb文件路径),运行之后即可在ipynb文件夹下生成一个base.html文件,可以用浏览器打开查看笔记内容。

    下面我们再将py文件转化为可执行程序。在ipynb_view文件夹下打开命令行窗口,输入pyinstaller ipynb_view.py即创建完成。

    之后只要找到一个.ipynb文件,设置打开方式默认是ipynb_view.exe,以后每次双击.ipynb文件都会在.ipynb所在文件夹下生成一个同名的.html文件,速度还是很快的,这样查看笔记就方便多了。

    改进方向

    上面只是提供一个思路和简单的实现,还不是十分完善,感兴趣的读者可以再自己把代码完善起来,可以有以下改进方向作为参考

    • 第一是这样每次生成的一个html文件,都要手动删除。如果可以用程序控制把HTML内容直接用浏览器打开就更好了,或者编写用完自动删除的代码

    • 第二是上面创建html代码python代码可读性不强,只是因为需求比较简单,暂时应付一下,有更高需求的读者可以试一试编写一个添加标签、属性、css样式的类,让代码结构更加清晰。或者用现成的pyH库貌似可以实现

    • 第三是文本内容没有加进来,因为里面有各种markdown格式标记,不是很好处理,这里就直接舍弃了,有需要的读者可以写程序把文本也读取进来

      本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
      转藏 分享 献花(0

      0条评论

      发表

      请遵守用户 评论公约

      类似文章 更多