python创建可以打开文件的EXE

浏览: 1863

image.png

(注:本文首发于数据取经团微信公众号)

首先抛出一个要解决的问题,在学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文件时传入参数
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 = '' # 添加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 += '' + '\n' # 这个标签可以把里面的内容原样输出<br /> for i in d['source']:<br /> s += i.rstrip() + '\n'<br /> s += '
    \n'
    elif d['cell_type'] == 'markdown': # 提取标题
    result = re.findall('#+ .+',d['source'][0])
    if result:
    n = result[0].count('#') # 查看几级标题
    result1 = re.sub('#+ ','',result[0])
    s += '' + result1 + '' + '\n'
    contents += '
  • ' + ' '*(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格式标记,不是很好处理,这里就直接舍弃了,有需要的读者可以写程序把文本也读取进来

专栏信息

专栏主页:Data Analysis

推荐 1
本文由 dwzb 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册