docker-compose快速搭建python开发环境

Docker提供了容器级别的资源隔离。由于Python的外部依赖管理中存在的问题,我们通常会使用virtualenv来对不同的项目创建其唯一的依赖环境。这时利用Docker进行Python开发,可以轻松解决不同Python项目之间的依赖隔离问题。

作为应用程序,我们通常需要依赖于多种外部服务,比如数据库、缓存服务等等。Docker-compose就是在Docker容器的基础上,提供了统一的容器编排语言,可以让你更轻松的利用Docker构建你的应用环境。

编写Dockerfile

我们使用requirements.txt定义我们的第三方python包依赖
Python
Project-Root
|– static
|– templates
|– server.py
|– requirements.txt
|– Dockerfile
|– docker-compose.yml

编写Dockerfile内容如下:
Python
在Dockerfile中,我们主要目的:通过requirements.txt文件安装第三方的Python库依赖;利用Docker的容器隔离,可以忽略掉很多在本地开发中需要使用的东西,比如virtualenv。

编排我们的Docker容器

在案例中,应用程序依赖了mongodb作为数据存储服务,以及redis作为缓存服务。在一般情况下,作为开发团队要么我们搭建统一的mongodb;要不就每个人在开发机上单独部署。

而在Docker中,我们则不在需要做这么多无用的事情。 Docker官方提供了大量的基础容器,基本涵盖了日常开发中我们需要的大部分依赖。 在https://hub.docker.com/我们可以搜索到我们需要的基础镜像。

比如mongodb以及redis,在docker-hub上官方都提供了容器话的服务。

以redis容器为例,我们在本地搭建redis服务要做的事情主要包括两步:
Python
这个时候我们就可以通过访问0.0.0.0:63775来访问我们的redis服务器了。

我们也可以通过Docker原生的命令来连接我们的应用容器和redis容器,以使我们的代码能够正常的访问redis服务
Python
而事实上,我们可以使用更加简化的方式来定义我们的容器组合管理,使用Docker-compose(前身Fig)来定义我们的容器组合关系。
Python
这里我们定义了3个容器web、redis、mongo。 其中,web容器是通过当前目录的Dockerfile进行构建,同时将当前目录挂在到/app目录。 而redis和mongo则直接使用官方进行。

通过使用links,我们可以在web容器中通过 ‘redis:6375’以及’mongo:21707’直接访问相应的服务。

开始Coding吧

Python
Docker会根据当前的目录下得Dockerfile构建基础镜像,并且使用python server.py运行程序,并且运行redis以及mongo服务。

同时由于使用了volumes挂载了本地目录到/app,此时如果我们是开启的Debug模式,我们就可以直接在本地使用你喜欢的文本编辑器去编写代码,并且更新的代码能够实时被重新加载。

当然在使用Docker中最漫长的过程就是,下镜像,下镜像&下镜像。
Python

利用python探测谷歌搜索可用IP

原理是查询_netblocks.google.com域名的TXT记录,这个记录有大量网段的谷歌IP,再探测443端口开放的IP。不过探测出开放443端口的IP后,可能还要使用curl来检测是不是谷歌搜索的服务器。这一步需要与443端口ssl握手,但验证证书是否一致,使用python暂时写不出来,可以用curl https://www.google.com –resolve www.google.com:443:1.2.3.4,其中1.2.3.4为要探测的谷歌IP。
python脚本:

#!/usr/bin/python
# -*- coding:utf-8 -*-
'''
install modules:
pip install dnspython
'''

import dns.resolver
import struct, socket
import re
import sys
import threading
import Queue

threadLock = threading.Lock()
SHARE_Q = Queue.Queue()  
_WORKER_THREAD_NUM = 10
GLOBAL_COUNTER = 0

class MyThread(threading.Thread) :

    def __init__(self, func) :
        super(MyThread, self).__init__()
        self.func = func

    def run(self) :
        self.func()


def worker() :
    global SHARE_Q
    global GLOBAL_COUNTER
    while not SHARE_Q.empty():
        item = SHARE_Q.get()

        if check_port(item):
            with threadLock:
                print(item)
                GLOBAL_COUNTER += 1
                if GLOBAL_COUNTER >= 100:
                    sys.exit(0)

def get_txt_record(domain):
    answers = dns.resolver.query(domain, 'TXT')
    for rdata in answers:
        return str(rdata)


def get_ip_range_from_txt_record(txt_record):
    ip_range = []
    re_ret = re.findall(r'ip4:([^ ]+)', txt_record)
    for ip_mask in re_ret:
        ip_range.append(ip_mask)

    return ip_range

def get_ip_from_cidr(ip_range):
    ips = []
    for ip_mask in ip_range:
        (ip, cidr) = ip_mask.split('/')
        cidr = int(cidr) 
        host_bits = 32 - cidr
        i = struct.unpack('>I', socket.inet_aton(ip))[0] # note the endianness
        start = (i >> host_bits) << host_bits # clear the host bits
        end = i | ((1 << host_bits) - 1) 

        for i in range(start, end):
            ips.append(socket.inet_ntoa(struct.pack('>I',i)))

    return ips

def check_port(address, port=443):
    s=socket.socket()
    s.settimeout(1)  
    try:
        s.connect((address,port))
        return True
    except socket.error,e:
        return False

def main():
    txt_record = get_txt_record("_netblocks.google.com")
    ip_range = get_ip_range_from_txt_record(txt_record)
    ips = get_ip_from_cidr(ip_range)

    global SHARE_Q
    threads = []
    for task in ips :  
        SHARE_Q.put(task)

    for i in xrange(_WORKER_THREAD_NUM) :
        thread = MyThread(worker)
        thread.start()
        threads.append(thread)
    for thread in threads :
        thread.join()


if __name__ == '__main__':
    main()

shell脚本:


while read ip;do if curl -s -m 3 https://www.google.com.hk --resolve www.google.com.hk:443:$ip -o /dev/null;then echo $ip fi done < ip.txt

使用python MySQLdb操作mysql数据库

MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的。

如何安装MySQLdb?

为了用DB-API编写MySQL脚本,必须确保已经安装了MySQL。复制以下代码,并执行:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

如果执行后的输出结果如下所示,意味着你没有安装 MySQLdb 模块:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    import MySQLdb
ImportError: No module named MySQLdb

安装MySQLdb,请访问 http://sourceforge.net/projects/mysql-python ,(Linux平台可以访问:https://pypi.python.org/pypi/MySQL-python)从这里可选择适合您的平台的安装包,分为预编译的二进制文件和源代码安装包。
如果您选择二进制文件发行版本的话,安装过程基本安装提示即可完成。如果从源代码进行安装的话,则需要切换到MySQLdb发行版本的顶级目录,并键入下列命令:

$ gunzip MySQL-python-1.2.2.tar.gz
$ tar -xvf MySQL-python-1.2.2.tar
$ cd MySQL-python-1.2.2
$ python setup.py build
$ python setup.py install

** 注意 ** :请确保您有root权限来安装上述模块。

数据库连接

连接数据库前,请先确认以下事项:
– 您已经创建了数据库 TESTDB.
– 在TESTDB数据库中您已经创建了表 EMPLOYEE
– EMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。
– 连接数据库TESTDB使用的用户名为 “testuser” ,密码为 “test123”,你可以可以自己设定或者直接使用root用户名及其密码,Mysql数据库用户授权请使用Grant命令。
– 在你的机子上已经安装了 Python MySQLdb 模块。

实例:

以下实例链接Mysql的TESTDB数据库:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# 使用execute方法执行SQL语句
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法获取一条数据库。
data = cursor.fetchone()

print "Database version : %s " % data

# 关闭数据库连接
db.close()

执行以上脚本输出结果如下:

Database version : 5.0.45

创建数据库表

如果数据库连接存在我们可以使用execute()方法来为数据库创建表,如下所示创建表EMPLOYEE:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# 如果数据表已经存在使用 execute() 方法删除表。
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")

# 创建数据表SQL语句
sql = """CREATE TABLE EMPLOYEE (
         FIRST_NAME  CHAR(20) NOT NULL,
         LAST_NAME  CHAR(20),
         AGE INT,  
         SEX CHAR(1),
         INCOME FLOAT )"""

cursor.execute(sql)

# 关闭数据库连接
db.close()

数据库插入操作

以下实例使用执行 SQL INSERT 语句向表 EMPLOYEE 插入记录:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
         LAST_NAME, AGE, SEX, INCOME)
         VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
   # 执行sql语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # Rollback in case there is any error
   db.rollback()

# 关闭数据库连接
db.close()

以上例子也可以写成如下形式:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, 
       LAST_NAME, AGE, SEX, INCOME) 
       VALUES ('%s', '%s', '%d', '%c', '%d' )" % 
       ('Mac', 'Mohan', 20, 'M', 2000)
try:
   # 执行sql语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()

** 实例:**
以下代码使用变量向SQL语句中传递参数:

..................................
user_id = "test123"
password = "password"

con.execute('insert into Login values("%s", "%s")' % 
             (user_id, password))
..................................

数据库查询操作

Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据。
– fetchone(): 该方法获取下一个查询结果集。结果集是一个对象
– fetchall():接收全部的返回结果行.
– rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。
** 实例:**
查询EMPLOYEE表中salary(工资)字段大于1000的所有数据:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE 
       WHERE INCOME > '%d'" % (1000)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 获取所有记录列表
   results = cursor.fetchall()
   for row in results:
      fname = row[0]
      lname = row[1]
      age = row[2]
      sex = row[3]
      income = row[4]
      # 打印结果
      print "fname=%s,lname=%s,age=%d,sex=%s,income=%d" % 
             (fname, lname, age, sex, income )
except:
   print "Error: unable to fecth data"

# 关闭数据库连接
db.close()

以上脚本执行结果如下:

fname=Mac, lname=Mohan, age=20, sex=M, income=2000

数据库更新操作

更新操作用于更新数据表的的数据,以下实例将 EMPLOYEE 表中的 SEX 字段为 ‘M’ 的 AGE 字段递增 1:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()

删除操作

删除操作用于删除数据表中的数据,以下实例演示了删除数据表 EMPLOYEE 中 AGE 大于 20 的所有数据:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交修改
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭连接
db.close()

执行事务

事务机制可以确保数据一致性。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
– 原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
– 一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
– 隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
– 持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
Python DB API 2.0 的事务提供了两个方法 commit 或 rollback。
实例:

# SQL删除记录语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 向数据库提交
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

对于支持事务的数据库, 在Python数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。
commit()方法游标的所有更新操作,rollback()方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。
错误处理
DB API中定义了一些数据库操作的错误及异常,下表列出了这些错误和异常:

异常 描述
Warning 当有严重警告时触发,例如插入数据是被截断等等。必须是 StandardError 的子类。
Error 警告以外所有其他错误类。必须是 StandardError 的子类。
InterfaceError 当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。 必须是Error的子类。
DatabaseError 和数据库有关的错误发生时触发。 必须是Error的子类。
DataError 当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。 必须是DatabaseError的子类。
OperationalError 指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是DatabaseError的子类。
IntegrityError 完整性相关的错误,例如外键检查失败等。必须是DatabaseError子类。
InternalError 数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。 必须是DatabaseError子类。
ProgrammingError 程序错误,例如数据表(table)没找到或已存在、SQL语句语法错误、 参数数量错误等等。必须是DatabaseError的子类。
NotSupportedError 不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上 使用.rollback()函数,然而数据库并不支持事务或者事务已关闭。 必须是DatabaseError的子类。

使用Python URLLIB3下载文件

urllib3是一个轻量级的python库,提供了线程安全,HTTP连接池和重用,文件发送等。

Python
为了演示urllib3的使用,我们这里将会从一个网站下载两个文件。
首先,需要导入urllib3库:

import urllib3

这两个文件的源url为:

url1 = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.csv'
url2 = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv'

现在开始创建一个HTTP连接池:

http = urllib3.PoolManager()

然后请求第一个文件并写入到文件:

response = http.request('GET', url1)
with open('all_week.csv', 'wb') as f:
    f.write(response.data)

然后是第二个文件:

response = http.request('GET', url2)
with open('all_month.csv', 'wb') as f:
    f.write(response.data)

最后释放这个HTTP连接:

response.release_conn()

安装并使用python requests发送http请求

Requests是一个Apache2 Licensed HTTP库,使用python编写。旨在设计成为易用的http请求库。意味着你不需要手动添加请求字符串到url,或者对POST数据进行表单编码。

安装Requests

有多种方法来安装requests库,如pip,easy_install和编译安装。
这里推荐pip,如执行:

pip install requests 

导入requests模块

要能够在python使用requests库,必须导入正确的模块。可以在脚本头部添加:

import requests 

发送请求

如获取一个网页的内容

r = request.get(‘https://github.com/timeline.json’)

获取响应状态码

发送请求后,准备往下对网页内容或url进一步处理时,最好先检查一下响应状态码。如下示例:

r = requests.get('https://github.com/timeline.json')
r.status_code
>>200

r.status_code == requests.codes.ok
>>> True

requests.codes['temporary_redirect']
>>> 307

requests.codes.teapot
>>> 418

requests.codes['o/']
>>> 200

获取内容

当web服务器返回响应体后,就可以收集你所需的内容了。

import requests
r = requests.get('https://github.com/timeline.json')
print r.text

# The Requests library also comes with a built-in JSON decoder,
# just in case you have to deal with JSON data

import requests
r = requests.get('https://github.com/timeline.json')
print r.json

查看响应头

通过使用python字典,可以访问和查看服务器的响应头。

r.headers
{
    'status': '200 OK',
    'content-encoding': 'gzip',
    'transfer-encoding': 'chunked',
    'connection': 'close',
    'server': 'nginx/1.0.4',
    'x-runtime': '148ms',
    'etag': '"e1ca502697e5c9317743dc078f67693f"',
    'content-type': 'application/json; charset=utf-8'
}

r.headers['Content-Type']
>>>'application/json; charset=utf-8'

r.headers.get('content-type')
>>>'application/json; charset=utf-8'

r.headers['X-Random']
>>>None

# Get the headers of a given URL
resp = requests.head("http://www.google.com")
print resp.status_code, resp.text, resp.headers

自定义请求头

如果想要添加自定义请求头到一个请求,必须传递一个字典到headers参数。

import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}

r = requests.post(url, data=json.dumps(payload), headers=headers)

发送一个POST请求

requests库也可以发送post请求,如下:

r = requests.post(http://httpbin.org/post)

当然也可以发送其它类型的请求,如 PUT, DELETE, HEAD和OPTIONS.

r = requests.put("http://httpbin.org/put")
r = requests.delete("http://httpbin.org/delete")
r = requests.head("http://httpbin.org/get")
r = requests.options("http://httpbin.org/get")

可以使用这些方法完成很多复杂的工作,如使用一个python脚本来创建一个GitHub repo。

import requests, json

github_url = "https://api.github.com/user/repos"
data = json.dumps({'name':'test', 'description':'some test repo'})
r = requests.post(github_url, data, auth=('user', '*****'))

print r.json

使用virtualenv创建一个虚拟,多版本和独立的python开发环境

Virtualenv是一个用来创建虚拟的python开发环境的工具,可以使用它创建多个相互隔离的python环境而不需要担心影响到其它的python项目环境。

它可以为每个python项目创建独立的环境。它实际上没有单独的为每个python项目安装python副本,而是提供了一个方法来隔离各自的项目环境。

验证Virtualenv是否已经安装

执行如下命令来验证机器是否已经安装有Virtualenv:

virtualenv --version

如果看到输出版本号,如1.6.1,则表明已经安装有virtualenv。

安装virtualenv

有多种方法来安装virtualenv。
ubuntu和debian安装:

$ sudo apt-get install python-virtualenv

使用easy_install安装:

$ sudo easy_install virtualenv

使用pip安装

$ sudo pip install virtualenv

配置和使用Virtualenv

一旦安装好virtualenv,就可以开始创建自己的python环境了。
首先为隔离环境创建一个目录

mkdir ~/virtualenvironment

再为你的应用创建一个完整干净的python副本目录

virtualenv -p /usr/bin/python2.7 ~/virtualenvironment/my_new_app

其中-p为指定的python版本路径。
进到项目目录,激活你的虚拟环境

cd ~/virtualenvironment/my_new_app/bin

激活虚拟环境

source activate

现在注意到你已经进入虚拟环境了,现在你使用pip或easy_install安装的python包都会保存到my_new_app/lib/python2.7/site-packages目录
要退出虚拟环境,只需要键入”deactivate”

Virtualenv如何实现虚拟环境的

安装在你项目目录的python包不会影响到全局的python安装目录

Virtualenv不会创建每一个python文件来实现一个新的python环境

为了节省空间,使用了软链接来链接到全局环境的文件中并能加速虚拟环境创建

因此,必须已经有一个python环境安装在你的主机上

在你的Virtualenv安装一个包

执行如下命令:

pip install flask

CentOS 7编译安装及yum安装Python 3

最新的CentOS 7,默认的python版本仍然是python2.7,且python3也不在base仓库中。如果你的python应用程序依赖python3,在CentOS 7中有两种方法来安装Python 3。

从源码编译安装Python3

从源码编译安装python3是最通用的一种安装方法。因为你能选择安装的python3的版本,可以确切清楚安装python所需的依赖。

首先,安装所需工具:

$ sudo yum install yum-utils

然后使用yum-builddep,为python3配置一个必须的构建环境和安装所需的依赖。如下命令:

$ sudo yum-builddep python

现在从https://www.python.org/ftp/python/下载python3版本,如python3.5

$ curl -O https://www.python.org/ftp/python/3.5.0/Python-3.5.0.tgz

最后,按如下步骤安装python3。默认的安装路径为/usr/local。如果需要更改到其它目录,指定编译参数–prefix=/alternative/path。

$ tar xf Python-3.5.0.tgz
$ cd Python-3.5.0
$ ./configure
$ make
$ sudo make install

执行完成后将安装python3,pip3,setuptools以及python3的库。

$ python3 --version

从EPEL yum安装python3

最新的EPEL 7仓库提供python3的安装。因此如果你使用的是CentOS7,你可以非常容易地安装python3了。执行如下命令启用EPEL仓库:

$ sudo yum install epel-release

然后使用yum安装python3.4

$ sudo yum install python34

注意这时是没有安装有pip的。要安装pip和setuptools,需要执行如下命令:

$ curl -O https://bootstrap.pypa.io/get-pip.py
$ sudo /usr/bin/python3.4 get-pip.py

Python

python tkinter 窗口居中对齐

tkinter没有现成的窗口居中的功能,只能间接地算出来。

  1. from Tkinter import *
  2. def center_window(w=300, h=200):
  3.     # get screen width and height
  4.     ws = root.winfo_screenwidth()
  5.     hs = root.winfo_screenheight()
  6.     # calculate position x, y
  7.     x = (ws/2) – (w/2)   
  8.     y = (hs/2) – (h/2)
  9.     root.geometry(‘%dx%d+%d+%d’ % (w, h, x, y))
  10. root = Tk()
  11. center_window(500, 300)
  12. root.mainloop()

使用pyinstaller打包python为exe文件

最近用python的tkinter写了个windows界面的工具,用来对软件版本发布的自动化,之前发布版本是由PHP的同事完成,又是手动上传文件到ftp,又是修改数据库,php代码等这么多繁琐的步骤。所以决定用python写了个windows的应用,因为版本发布可能会交给运营的同事完成,所以用tkinter写了个界面,顺便转换成exe的文件,之前是用py2exe,觉得不好用,搜索到了pyinstaller,还不错,使用简单,且打包成exe兼容性好,下面记录方法。
1、下载pyinstaller
目前pyinstaller支持的python版本为2.3-2.7,可以到http://www.pyinstaller.org/官网下载。
2、安装
下载完成后,解压即可。
3、使用方法
使用也非常的简单,cmd下进入解压出来的目录,执行如下命令。

  1. python pyinstaller.py [opts] yourprogram.py

主要选项包括:
-F, –onefile 打包成一个exe文件。
-D, –onedir 创建一个目录,包含exe文件,但会依赖很多文件(默认选项)。
-c, –console, –nowindowed 使用控制台,无界面(默认)
-w, –windowed, –noconsole 使用窗口,无控制台

更详细的使用方法请参考下载包里的doc目录下的Manual.html文件。

Linux下python升级

安装python2.7

  1. cd /tmp
  2. wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz
  3. tar xzf Python-2.7.3.tgz
  4. cd Python-2.7.3
  5. ./configure && make && make install
  6. ln -sf /usr/local/bin/python /usr/bin/python
  1. [root@localhost ~]# python -V
  2. Python 2.7.3

修复yum
编辑/usr/bin/yum,把/usr/bin/python 改为/usr/bin/python2.4