Fork me on GitHub
Suzf  Blog

Tag Python

How-to: use Python send mail with To Cc and Bcc

# -*- coding:utf-8 -*-

import smtplib
from email.mime.text import MIMEText

to = ['zfsu']
cc = ['zfsu','root']
bcc = ['jack']
from_addr = 'root'
message_subject = "Say Hello"
message_text = "Hello world"
message = "From: %s\r\n" % from_addr \
        + "To: %s\r\n" % ",".join(to) \
        + "CC: %s\r\n" % ",".join(cc) \
        + "BCC: %s\r\n" % ",".join(bcc) \
        + "Subject: %s\r\n" % message_subject \
        + message_text
to_addrs = to + cc + bcc
server = smtplib.SMTP('localhost')
server.sendmail(from_addr, to_addrs, message)


Use Python send mail

I recommend that you use the standard packages email and smtplib together to send Email. Please look at the following example (reproduced from the Python documentation). Notice that if you follow this approach, the "simple" task is indeed simple, and the more complex tasks (like attaching binary objects or sending plain/HTML multipart messages) are accomplished very rapidly.

Here are a few examples of how to use the email package to read, write, and send simple email messages, as well as more complex MIME messages.

First, let’s see how to create and send a simple text message:

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.mime.text import MIMEText

# Open a plain text file for reading.  For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(

# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you

# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())

For sending email to multiple destinations, you can also follow the example in the Python documentation:

# Import smtplib for the actual sending function
import smtplib

# Here are the email package modules we'll need
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart


# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'Our family reunion'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = COMMASPACE.join(family)
msg.preamble = 'Our family reunion'

# Assume we know that the image files are all in PNG format
for file in pngfiles:
    # Open the files in binary mode.  Let the MIMEImage class automatically
    # guess the specific image type.
    fp = open(file, 'rb')
    img = MIMEImage(

# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
s.sendmail(me, family, msg.as_string())

As you can see, the header To in the MIMEText object must be a string consisting of email addresses separated by commas. On the other hand, the second argument to the sendmail function must be a list of strings (each string is an email address).

So, if you have three email addresses: [email protected], [email protected], and [email protected], you can do as follows (obvious sections omitted):

to = ["[email protected]", "[email protected]", "[email protected]"]
msg['To'] = ",".join(to)
s.sendmail(me, to, msg.as_string())

the "","".join(to) part makes a single string out of the list, separated by commas.

From your questions I gather that you have not gone through the Python tutorial - it is a MUST if you want to get anywhere in Python - the documentation is mostly excellent for the standard library.


Python 执行Linux系统命令的N种方法

I. os
system(command) -> exit_status
Execute the command (a string) in a subshell.

# os.system() 是新起一个shell去干活的,对系统的开销比较大
# 仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息
# 无法控制,(如果调用的外部命令,挂死或者执行时间很长),主进程无法控制os.system(), 因为调用os.system(cmd)  调用进程会block, until os.system() 自己退出

In [30]: import os

In [31]: os.system('ls *.py')
Out[31]: 0

popen(command [, mode='r' [, bufsize]]) -> pipe
Open a pipe to/from a command returning a file object.

# 该方法不但执行命令还返回执行后的信息对象
# 好处在于:将返回的结果赋于一变量,便于程序的处理

In [32]: py = os.popen('ls *py').readlines()

In [33]: print py
['\n', '\n', '\n', '\n', '\n', '\n', '\n']


II. commands

In [40]: import commands

In [41]: commands.getoutput('ls *.py')
Out[41]: '\\\\\\'

In [41]: commands.getstatusoutput('ls *py')


III. subprocess  [ 推荐使用 ]
# 运用对线程的控制和监控,将返回的结果赋于一变量,便于程序的处理
# 会自动地加载系统环境变量。
相对应的subprocess 模块里有 call 函数和 popen 函数 。

call 函数的用法如下:, *, stdin=None, stdout=None, stderr=None, shell=False)

In [64]: import subprocess

In [65]:'ls *py ',shell=False)
Out[65]: 0

交互式模式下,call 也会有returncode 0 输出,不过在py文件里执行时,ruturn的结果并不会将最后的 0 输出。不过在使用call 函数时,需要注意后面的几个参数:

    Using shell=True can be a security hazard. See the warning under Frequently Used Arguments for details.
    Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. Use Popen with the communicate() method when you need pipes. 主要用于替换 os.system ,具体如下:

In [66]:'date')
Thu Oct 29 16:02:24 CST 2015
Out[66]: 0


subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)


In [67]: import subprocess

In [68]: p = subprocess.Popen('ls *.py', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

In [69]: print p.stdout.readlines()
['\n', '\n', '\n', '\n', '\n', '\n', '\n']




Python 2.6 升级安装 2.7遇到的readline问题

通过上 一篇文章 脚本升级Python到2.7 之后发现一个问题, 在python/iPython交互器(命令行下)不能使用删除/上下键 无语法高亮 ,非常不方便。 检索相关信息,发现pypi有单独的readline模块 pip 安装
^_^[16:29:48][[email protected] ~]#pip install readline
Collecting readline
/usr/local/lib/python2.7/site-packages/pip-7.1.2-py2.7.egg/pip/_vendor/requests/packages/urllib3/util/ InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see
  Downloading readline- (2.3MB)
    100% |████████████████████████████████| 2.3MB 88kB/s
Installing collected packages: readline
  Running install for readline
Successfully installed readline-
下载后解压安装python install
/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
error: command 'gcc' failed with exit status 1
原因是未找到ncurses,需要安安装ncurses-devel包后再次安装readline,提示成功,enjoy! FAQ:
    creating build/lib.linux-x86_64-2.7
    gcc -pthread -shared build/temp.linux-x86_64-2.7/Modules/2.x/readline.o readline/libreadline.a readline/libhistory.a -lncurses -o build/lib.linux-x86_64-2.7/
    gcc: readline/libreadline.a: No such file or directory
    gcc: readline/libhistory.a: No such file or directory
    error: command 'gcc' failed with exit status 1

    readline 是Python的一个内建模块,你看到这些错误信息是因为系统没有完成重建。可能是系统中缺少 patch 包。
    你可以试试 yum install patch

Python 版本升级shell简略版

尽管Python3很早之前就出现了但是现在很多企业用的还是2.7居多 天朝系统版本CentOS居多 故以CentOS6为实验环境 Python 从 2.6 升级到 2.7 OoO
# Desc: Python && pip upgrade
# Author:
# Mail: [email protected]
# Date:  Oct 09, 2014
# Home:

PY_OLD_VERSION=`python -V 2>&1 | awk '{print $2}'`

function prepare_work(){

  yum -y install zlib  openssl openssl-devel curl wget gcc patch ncurses-devel
  # yum install ipython 


function python_upgrade(){

  cd ${DOWN_PATH}
  wget -c${PY_VERSION}/Python-${PY_VERSION}.tgz
  tar zxf Python-${PY_VERSION}.tgz
  cd Python-${PY_VERSION}
  ./configure --prefix=/usr/local/Python${PY_VERSION} --enable-shared
  make && make install
  mv /usr/bin/python /usr/bin/python_${PY_OLD_VERSION}
  cp /usr/bin/yum{,.old} && sed -i s/python/python${PY_OLD_VERSION}/ /usr/bin/yum

  ln -s /usr/local/Python${PY_VERSION}/bin/${PY_BIN_NAME} /usr/bin/python


function pip_upgrade(){

  cd ${DOWN_PATH}
  curl -O
  tar zxf setuptools-2.0.tar.gz
  cd setuptools-2.0
  python build && python install

  cd ${DOWN_PATH}
  curl -O
  tar zxf pip-7.1.2.tar.gz     
  cd pip-7.1.2    
  python install
  mv /usr/bin/pip{,.old}  && ln -s /usr/local/Python${PY_VERSION}/bin/pip /usr/bin/pip
  pip install readline



Flask_Faq : AttributeError: 'module' object has no attribute 'autoescape'

前些天从 "spider_net" 上找了一篇文章 , 大致就是利用 highcharts + flask + mysql 构建的一个简单的监控系统 ,
经过几番挣扎终于还是给捣持出来了 , 现在总结一下 , 分享给大家 . o_O


* Detected change in '', reloading
* Restarting with reloader
X.X.X.X - - [11/Jun/2015 15:24:14] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
File "/usr/lib64/python2.6/site-packages/jinja2/", line 195, in import_string
return getattr(__import__(module, None, None, [obj]), obj)
AttributeError: 'module' object has no attribute 'autoescape'

yum install python-pip -y
pip install --upgrade jinja2

redhat 官方宣称这是一个bug , for more :

Python pip 简单使用说明

简单来说 pip 就是 Python 的一个包管理工具, 和 yum / apt-get 有异曲同工之妙 。
好了, 会到正文

# yum install python-pip -y


# wget "" --no-check-certificate
# tar -xzvf pip-1.5.4.tar.gz
# cd pip-1.5.4 && python install

# 升级
pip install --upgrade pip

2. 常用操作
# 安装
# pip install pkgname
# python2 -m pip install pkgname
# python3 -m pip install pkgname

# 卸载
# pip uninstall pkgname

# 升级
# pip install --upgrade pkgname

# 检测更新
# pip list --outdated

# 查看
# pip show --files pkgname

# 查看某个库的信息:
# pip show Jinja2

# 查看已经安装的库:
pip list    or   pip freze

3. FAQ :

ImportError No module named setuptools
请参考《ImportError No module named setuptools解决》

4. 参数说明
# pip -h
pip [options]

install 安装包.
uninstall 卸载包.
freeze 按着一定格式输出已安装包列表
list 列出已安装包.
show 显示包详细信息.
search 搜索包,类似yum里的search.
wheel Build wheels from your requirements.
zip 不推荐. Zip individual packages.
unzip 不推荐. Unzip individual packages.
bundle 不推荐. Create pybundles.
help 当前帮助.

General Options:
-h, --help 显示帮助.
-v, --verbose 更多的输出,最多可以使用3次
-V, --version 现实版本信息然后退出.
-q, --quiet 最少的输出.
--log-file 覆盖的方式记录verbose错误日志,默认文件:/root/.pip/pip.log
--log 不覆盖记录verbose输出的日志.
--proxy Specify a proxy in the form [user:[email protected]]proxy.server:port.
--timeout 连接超时时间 (默认15秒).
--exists-action Default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup.
--cert 证书.

Learn more :

Python 设置终端显示颜色、粗体、下划线等效果





#! /usr/bin/python                                                          
# -*- coding: utf-8
        'fore': {
                'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
                'blue': 34, 'purple': 35, 'cyan': 36, 'white': 37,
        'back': {
                'black': 40, 'red': 41, 'green': 42, 'yellow': 43,
                'blue': 44, 'purple': 45, 'cyan': 46, 'white': 47,
        'mode': {
                'bold': 1, 'underline': 4, 'blink': 5, 'invert': 7,
        'default': {
                'end': 0,
def use_style(string, mode='', fore='', back=''):
    mode = '%s' % STYLE['mode'][mode] if STYLE['mode'].has_key(mode) else ''
    fore = '%s' % STYLE['fore'][fore] if STYLE['fore'].has_key(fore) else ''
    back = '%s' % STYLE['back'][back] if STYLE['back'].has_key(back) else ''
    style = ';'.join([s for s in [mode, fore, back] if s])
    style = '\033[%sm' % style if style else ''
    end = '\033[%sm' % STYLE['default']['end'] if style else ''
    return '%s%s%s' % (style, string, end)
def test():
    print use_style('Normal')
    print use_style('Bold', mode='bold')
    print use_style('Underline & red text', mode='underline', fore='red')
    print use_style('Invert & green back', mode='reverse', back='green')
    print use_style('Black text & White back', fore='black', back='white')
if __name__ == '__main__':


转自 Pythoner