Python脚本检测并安装依赖的第三方库

Python第三方库非常丰富,使用第三方库可以减少代码量,使代码逻辑更加清晰。我写脚本分享给朋友的时候,经常要提醒他这个脚本依赖哪些第三方库。如果缺第三方库,新手很难从报错和源代码中,推测出缺哪个库。那么是否可以让脚本自己检测缺少哪个库,并询问用户,然后安装呢?

requirements = ["pandas", "matplotlib", "seaborn"]
def check_requirement(package):
    try:
        exec("import {0}".format(package))
    except ModuleNotFoundError:
        inquiry = input("This script requires {0}. Do you want to install {0}? [y/n]".format(package))
        while (inquiry != "y") and (inquiry != "n"):
            inquiry = input("This script requires {0}. Do you want to install {0}? [y/n]".format(package))
        if inquiry == "y":
            import os
            print("Execute commands: pip install {0}".format(package))
            os.system("pip install {0}".format(package))
        else:
            print("{0} is missing, so the program exits!".format(package))
            exit(-1)
for requirement in requirements:
    check_requirement(requirement)
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

让进程在后台运行

1. 让进程在后台运行
Linux进程可以分为前台进程和后台进程,在终端输入命令执行的是前台进程模式。如果一个命令需要运行很久,就会阻塞终端,而且终端断开后命令也会跟着终止。所以我们可以把运行时间很长的任务使用后台模式运行。

$ python3 test.py &
在命令后面加&,它就会在后台运行了。

2. 查看后台运行进程

$ jobs
[1]+ 运行中  python3 test.py &

3. 将前台进程转入后台
有的时候忘记了在命令之后加上&,可以按下Ctrl+Z,把当前程序切换到后台。注意此时在后台的这个程序是处于Stopped状态。先用jobs查看任务的Job ID,然后使用bg命令让任务继续在后台运行。

$ jobs
[1]+ 已停止 python3 test.py
$ bg 1
[1]+ 运行中 python3 test.py &

4. 将后台进程切回前台
先用jobs查看任务的Job ID,然后使用fg命令将后台进程切换到前台

$ fg 1

5. nohup
不管是前台进程还是后台进程,在终端关闭的时候,Linux会发出终端关闭信号,让在终端中运行的进程结束。可以使用nohup命令,让程序运行的时候,忽略掉终端关闭的信号。使用nohup和&组合,可以让一个程序真正永远在后台执行。

$ nohup python3 test.py &

6. 重定向输出
如果后台程序输出到屏幕,即使后台运行,还是会输出到屏幕。这时候可以使用>将输出重定向到文件。

$ nohup python3 test.py 1> stdout.txt 2> stderr.txt  &
1是标准输出的文件描述符,可以省略。2是标准错误的文件描述符,可以通过2>&1重定向到标准输出。

Python处理临时文件

tempfile这个模块主要是用来创建临时文件和目录,用完后会自动删除,省的你自己去创建一个文件、使用这个文件、再删除这个过程了。其中比较常用的是TemporaryFile和NamedTemporaryFile。

import tempfile
import os
tmp1 = tempfile.TemporaryFile()   # 创建一个临时文件
type(tmp1)   # tempfile._TemporaryFileWrapper
tmp1.close()    # 关闭后,文件立即删除
tmp2 = tempfile.NamedTemporaryFile(delete=False) # 创建有名字的临时文件,且关闭后不立即删除
tmp2.name    # 'C:\Users\chenw\AppData\Local\Temp\tmpj9whdpr8'
os.path.exists(tmp2.name)   # True
tmp2.write("This is a tmp file!".encode())    # 不接收字符串(str),只能是字节流(bytes)
tmp2.seek(0)    # 调用read()函数前,需要调用seek()函数,指定读取指针的位置,参数是偏移量,0表示从头开始
tmp2.read()    # b'This is a tmp file!'   read()函数的返回值类型依然是bytes,而不是str
tmp2.close()    # 关闭后,文件不立即删除

Python发送邮件

Python提供了标准库smtplib用于发送邮件,整个过程非常简单,不足的地方是密码是明码。

import smtplib
from email.mime.text import MIMEText
#发件人
mail_from = "BioChen.com<admin@biochen.com>"
mail_host = "smtp.exmail.qq.com"
mail_usr = "admin@biochen.com"
mail_pwd = "pass_word"
#收件人
mail_to_addr = "pm.chenwen@qq.com"
#登录服务器
server = smtplib.SMTP(mail_host)
server.login(mail_usr,mail_pwd)
#邮件内容
content = 'this email is a test for python!'
msg = MIMEText(content,_subtype='plain')
msg['Subject'] = 'this email is a test for python!'
msg['From'] = mail_from
msg['To'] = mail_to_addr
#发送邮件
server.sendmail(mail_from, mail_to_addr, msg.as_string())
#关闭服务器
server.close()

网易和腾讯邮箱的SMTP服务器地址:

服务商 发件服务器 端口
网易163邮箱 smtp.163.com 25
网易企业邮 smtp.ym.163.com 25
腾讯QQ邮箱 smtp.qq.com 25
腾讯企业邮 smtp.exmail.qq.com 25

Ubuntu 18.04配置固定IP

Ubuntu 18.04不再使用ifupdown配置网络,而改用netplan。在/etc/network/interfaces配置固定IP是无效的,重启网络的命令services network restrart或/etc/init.d/networking restart也是无效的。
1. 使用ifupdown配置网络
如果要使用之前的方式配置网络,需要重新安装ifupdown:

sudo apt install ifupdown

修改配置文件/etc/network/interfaces:

sudo vim /etc/network/interfaces

配置文件修改如下:

iface ens160 inet static
address 210.72.92.25
gateway 210.72.92.254
netmask 255.255.255.0
dns-nameservers 8.8.8.8

重启网络服务使配置生效

sudo service network restrart

2. 使用netplan配置网络
Ubuntu 18.04使用netplan配置网络,其配置文件是yaml格式的。安装好Ubuntu 18.04之后,在/etc/netplan/目录下默认的配置文件名是50-cloud-init.yaml,我们通过VIM修改它:

sudo vim /etc/netplan/50-cloud-init.yaml

配置文件修改如下:

network:
    ethernets:
        ens160:
            addresses:
                - 210.72.92.28/24 # IP及掩码
            gateway4: 210.72.92.254 # 网关
            nameservers:
                addresses:
                    - 8.8.8.8 # DNS
    version: 2

无论是ifupdown还是netplan,配置的思路都是一致的,在配置文件里面按照规则填入IP、掩码、网关、DNS等信息。注意yaml是层次结构,需要缩进,冒号(:)表示字典,连字符(-)表示列表。
重启网络服务使配置生效:

sudo netplan apply

搭建远程Jupyter Notebook服务器

Jupyter Notebook是数据分析的一大神器,特别是可视化和分享功能强大。数据量大的时候,我的笔记本电脑有点吃力,于是想着在服务器上搭建Jupyter Notebook服务器。
1. 安装Jupyter Notebook库

$ pip3 install Jupyter

2. 生成Jupyter Notebook配置文件

$ jupyter notebook --generate-config
Writing default config to: /home/you/.jupyter/jupyter_notebook_config.py

3. 设置Jupyter Notebook密码

$ jupyter notebook password
Enter password: *******
Verify password: *******
[NotebookPasswordApp] Wrote hashed password to /home/chenwen/.jupyter/jupyter_notebook_config.json

4. 修改jupyter_notebook_config.py

c.NotebookApp.ip = '*'               #所有绑定服务器的IP都能访问
c.NotebookApp.port = 9999            #将端口设置为自己喜欢的吧,默认是8888
c.NotebookApp.open_browser = False   #我们并不想在服务器上直接打开Jupyter Notebook,所以设置成False

5. 启动Jupyter Notebook服务器,并让其在后台运行

$ jupyter notebook &amp;

6. 在自己的电脑上打开浏览器访问Jupyter Notebook服务器

输入密码后,就能像本地Jupyter Notebook一样使用啦。
更多细节请参考Jupyter Notebook官方文档:Running a notebook server

Google翻译API

Github上面其实有Google翻译的API,由于我国社会主义初级阶段的基本国情,直接拿来用好像行不通!

import requests
from bs4 import BeautifulSoup
def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        return r.text
    except:
        print("Get HTML Text Failed!")
        return 0
def google_translate(to_translate, from_language="en", to_language="ch-CN"):
    #根据参数生产提交的网址
    base_url = "https://translate.google.cn/m?hl={}&sl={}&ie=UTF-8&q={}"
    url = base_url.format(to_language, from_language, to_translate)
    #获取网页
    html = getHTMLText(url)
    if html:
        soup = BeautifulSoup(html, "html.parser")
    #解析网页得到翻译结果
    try:
        result = soup.find_all("div", {"class":"t0"})[0].text
    except:
        print("Translation Failed!")
        result = ""
    return result
print(google_translate("Hello World!"))
#你好,世界

代码好像超级简单哈,有空的话我想把它做成一个库。有github的给个星星呗,鼓励一下!
https://github.com/wen-chen/PyTransl

Python图像库Pillow

PIL(Python Imaging Library Python图像库)是一个强大的图像处理标准库,功能强大却又简单易用。现在的名字叫做Pillow。
安装Pillow

pip3 install pillow

如果你使用的是Anaconda开发环境,自带Pillow库。值得注意的是,导入Pillow库时,库的名称是PIL。下面我们将用Pillow库做一些有意思的事情。
1. 图像手绘效果

from PIL import Image
import numpy as np
a = np.asarray(Image.open('./picture.jpg').convert('L')).astype('float')
depth = 10. 					#(0-100)
grad = np.gradient(a)				#取图像灰度的梯度值
grad_x, grad_y = grad 				#分别取横纵图像梯度值
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.
A = np.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1./A
vec_el = np.pi/2.2 			        #光源的俯视角度,弧度值
vec_az = np.pi/4. 			        #光源的方位角度,弧度值
dx = np.cos(vec_el)*np.cos(vec_az) 	        #光源对x 轴的影响
dy = np.cos(vec_el)*np.sin(vec_az) 	        #光源对y 轴的影响
dz = np.sin(vec_el) 			        #光源对z 轴的影响
b = 255*(dx*uni_x + dy*uni_y + dz*uni_z) 	#光源归一化
b = b.clip(0,255)
im = Image.fromarray(b.astype('uint8')) 	#重构图像
im.save('./picture2.jpg')

图像效果如下:

2.生成数字验证码

from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
#随机字母:
def rndChar():
    return chr(random.randint(48, 57))
#随机颜色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
#随机颜色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
#240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
#创建Font对象:
font = ImageFont.truetype('ariblk.ttf', 40)
#创建Draw对象:
draw = ImageDraw.Draw(image)
#填充每个像素:
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=rndColor())
#输出文字:
for t in range(4):
    draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
#模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')

得到的数字验证码如下图:

windows中安装Tensorflow

TensorFlow 是一个用于人工智能的开源神器,我很想学习它。TensorFlow目前在windows平台上面只支持Python 3.5,我的电脑上面装的是Anaconda3-4.3.0.1,带的Python最新版本3.6。我不想将Python版本降级,于是就在虚拟环境中安装TensorFlow吧。
1. 创建TensorFlow虚拟环境
Win+R,运行”CMD”,输入以下命令

conda create --name tensorflow python=3.5

这样我就创建了一个名叫tensorflow的虚拟环境,当然你可以用任何你喜欢的名字代替。我还指定了Python版本是3.5。
2. 激活虚拟环境

activate tensorflow

如果想取消激活,使用deactivate命令即可

deactivate tensorflow

3. 安装TensorFlow

conda install tensorflow

Anaconda会自动安装TensorFlow和依赖关系
4. 安装Spyder和Jupyter Notebook
我非常喜欢用Spyder和Jupyter Notebook写Python代码。

conda install spyder
conda install jupyter notebook

这样我们的Windows TensorFlow开发环境就创建好了!
Win+R,运行”CMD”,

activate tensorflow
spyder

打开的是Spyder(Python3.5),而不是真实环境下的3.6。在交互窗口运行import tensorflow也没有报错,说明我们环境搭建成功。
更多Anaconda的用法参看我之前写得一篇博客:Python科学计算工具箱Anaconda

佛祖的灯芯

《大话西游》里有一段:
紫霞来到了驿站的外面,在院落里趴着一只黑狗,正在盯着紫霞,一个老者正在来回的奔波着,不断的在院子里取火,然后又跑进屋里去点灯。
“各位客官,请稍等一下,马上就好了。”
灯里面只有灯油,没有灯芯,当然没办法点着了,紫霞走了过去:“老伯啊,你这样是点不着的,你只有油,没有灯芯哎。”
“我知道,可是灯芯不见了,有什么办法呢?”
“再买一根喽。”
紫霞和二郎神化作的老头说了几句,老头忽然直起身来,看着紫霞,声音骤然一沉。
“你说得对,可是如来佛祖的那盏日月神灯的灯芯不见了,到哪里去买?”
没有灯芯点不着灯,那人心呢?