标签归档:Python

编译安装python3

从官网下载源码包

wget https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz

解压

tar xvzf Python-3.6.4.tgz

准备编译需要的依赖

yum install -y gcc zlib zlib-devel openssl openssl-devel

配置并编译

./configure --prefix=/usr/local/python3.6    # 设置安装位置
make
make install

添加环境变量。在/etc/profile文件末尾追加

PATH=$PATH:/usr/local/python3.6/bin
export PATH

使环境变量生效

source /etc/profile

测试,执行python3命令,查看输出

 

numpy中的dot矩阵乘法

本来以为这辈子都和数学没啥关系了,结果遇到了np.dot()。

numpy中的“*”和“dot”运算是完全不同的,前者是直接计算,后者是矩阵相乘。

(venv) [root@localhost tf]# python
Python 3.4.5 (default, May 29 2017, 15:17:55)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[1,2],[3,4]])
>>> c = a * b
>>> c
array([[ 1,  4],
       [ 9, 16]])
>>> d = np.dot(a, b)
>>> d
array([[ 7, 10],
       [15, 22]])

矩阵相乘:

例子:

 

CentOS 7安装Python3

在最新的CentOS版本7.3中,自带的Python版本依旧是2.7,而Django的建议版本已经到了3.x。所以需要安装新版本的Python,同时保留旧的Python环境。

首先安装epel源

yum install epel-release

查看可用的python3版本

yum list python3*

可以看见列表里提供Python 3.4

yum -y install python34

下面安装pip,python2.7和pyhon3.4的pip是可以同时存在的,默认分别为pip,pip3

yum install python-pip # 安装python2.7的pip
yum install python34-pip # 安装python3.4的pip,两者可以同时存在

查看pip版本信息

~# pip -V
pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)
~# pip3 -V
pip 8.1.2 from /usr/lib/python3.4/site-packages (python 3.4)

其实是一个东西,不过安装在了不同目录下。一般使用其中一个就行了。例如安装virtualenv

pip3 install virtualenv

使用virtualenv创建python3虚拟环境

virtualenv venv -p /bin/python3 --no-site-packages

Pypi国内镜像

清华大学镜像。pypi 镜像每 5 分钟同步一次。

修改后,在virtualenv环境也有效

  • 临时使用:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

注意,simple 不能少, 是 https 而不是 http

  • 设为默认:修改 ~/.pip/pip.conf (没有就创建一个), 修改 index-url至tuna,例如
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple

使用python发送邮件

使用python能够非常方便的发送邮件。只需要引入smtplib这个模块即可。下面是简单的示例代码:

import smtplib
from email.mime.text import MIMEText
from email.header import Header

mail_host="smtp.sendhost.com"
mail_user="sender@sendhost.com"
mail_pass="sender_password"

sender = 'send@receivehost.com'
receivers = ['receive@areceivehost.com']


def sendMail(content):
    message = MIMEText(content, 'plain', 'utf-8')
    message['From'] = Header("send_name", 'utf-8')
    message['To'] = Header("receive_name", 'utf-8')

    subject = 'sample_title'
    message['Subject'] = Header(subject, 'utf-8')

    try:
        smtpObj = smtplib.SMTP_SSL()
        #smtpObj.set_debuglevel(1)
        smtpObj.connect(mail_host, 465)
        smtpObj.login(mail_user,mail_pass)
        smtpObj.sendmail(sender, receivers, message.as_string())
        print "Send Mail Succeed"
    except smtplib.SMTPException:
        print "Error: Send Mail Failed"

如果使用非SSL方式则使用smptlib.SMTP()方法。

Python学习笔记(三)

闭包

如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。它只不过是个“内层”的函数,由一个名字(变量)来指
代,而这个名字(变量)对于“外层”包含它的函数而言,是本地变量。

看一个例子:

#!/usr/bin/python

def squ():
    fs = []
    for i in range(1, 4):    # range(1, 4) = [1, 2, 3]
        def f():
            return i*i
        fs.append(f)
    return fs

f1, f2, f3 = squ()    # same as f1 = squ()[0]

print f1()
print f2()
print f3()

执行这个函数,你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:

9
9
9

这是为什么呢?

首先明确,调用squ()后,squ()中存放的是三个f函数,而不是f函数计算出来的结果。

闭包 = 函数 + 引用环境,也就是说,当形成一个闭包之后,放进闭包的并不是具体的值。在上面的例子中,闭包中应该只包含变量i的地址,告诉程序当他被调用时这个i应该从哪里找,此时并不涉及i的值。只有当真正调用时,才根据此时i的值算出最终结果,而此时在返回3个函数之后,i的值已经成为3了,所以当我们开始调用函数时,返回的值就都是9了。

换一种写法理解起来应该容易

#!/usr/bin/python

def squ():
    fs = []
    for i in range(1, 4):
        def f():
            return i*i
        fs.append(f)
    return fs

print squ()[0]()

这样执行打出的结果将是:

9

当调用squ函数的时候,squ()这个list中存储的值是三个f函数,这三个f函数指向同一个变量i的地址。所以结果是一样的。

那么如何用第一个函数返回1, 4, 9呢? 只需要在squ函数被调用的时候,list中存储的f函数指向的参数值不同就行了,例如下面的写法:

#!/usr/bin/python

def squ():
    fs = []
    for i in range(1, 4):
        def f(j=i):
            return j*j    # if return i*i, answer will be 9
        fs.append(f)
    return fs

f1, f2, f3 = squ()

print f1()
print f2()
print f3()

f函数的值不再与i变化,而是记录下当前i的值用自己的参数j表示。

Python学习笔记(二)

Python基础

控制台输入

print()函数可以接受多个字符串,用逗号“,”隔开。print()会依次打印每个字符串,遇到逗号“,”会输出一个空格,这样就可以连成一串输出:

>>> print('The quick brown fox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog

python使用”%”作为替代符,与C类似:

>>> print('str: %s \nint: %d' % ('string', 100))
str: string 
int: 100

数据类型和运算

转义

使用”\”作为转义字符

# iamok.py
print('I\'m \"OK\"!')

$ python iamok.py
I'm "OK"

可以使用r’ ‘包含字符串进行整段文字的转义:

>>> print('abc\nde')
abc
de
>>> print(r'abc\nde')
abc\nde
>>> print('abc\\nde')
abc\nde

布尔值

布尔值包括True和False,需要区分大小写:

>>> True
True
>>> true
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'true' is not defined

空值

Python中的空值用None表示,不是Null

>>> None
>>> Null
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'Null' is not defined

除法

Python提供了“/”、“//”、“%”三种除法,三种除法结果如下:

>>> 10/3
3.3333333333333335
>>> 10//3
3
>>> 10%3
1

第一个结果结尾是5而不是3的原因可能和计算机二进制有关,没有深究。

编码

字符串编码规则十分复杂,这里不作深究。只需记住,通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

申明了UTF-8编码并不意味着你的.py文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码。

list

list是一个有序集合(有序集合不就是数组么,为啥还要叫集合?),基本用法如下:

>>> list = ['str1', 'str2', 'str3']
>>> list
['str1', 'str2', 'str3']
>>> len(list)
3
>>> list[0]
'str1'
>>> list[-1]
'str3'

确实就是集合嘛,可以用-1取最后的值,-n以此类推。

下面有一些对list的基本操作:

>>> list.append('str4')    # 在末尾加入元素
>>> list.insert(0,'str0')    # 在指定位置插入元素
>>> list
['str0', 'str1', 'str2', 'str3', 'str4']
>>> list.pop(3)    # pop出指定位置元素
'str3'
>>> list[2] = ['int0','int1']
>>> list
['str0', 'str1', ['int0', 'int1'], 'str4']    # 可以存在二维list
>>> list[2][1]
'int1'

tuple

和list唯一不同的地方在鱼tuple定义后不能修改。定义时使用”( )”而不是list的”[ ]”

需要注意的地方是只有一个元素时需要在结尾加上逗号

>>> t = (1)      # 错误,定义的是t=1,括号被解释成了数学上的小括号
>>> t = (1,)     # 正确

dict

字典,其实就是以Key-Value的方式存储的数据对:

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

要避免key不存在的错误,有两种办法,一是通过in判断key是否存在:

>>> 'Thomas' in d
False

二是通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:

>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

注意:返回None的时候Python的交互式命令行不显示结果。

要删除一个key,用pop(key)方法,对应的value也会从dict中删除:

>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key

set

set是数学意义上的集合,无序不重复,以list作为输入

>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

使用add和remove方法增减元素

>>> s.add(4)
>>> s
{1, 2, 3, 4}

两个set可以做数学意义上的交集、并集等操作:

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

代码逻辑

判断逻辑

使用if、elif、else三个保留字

age = 3
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')

循环逻辑

使用for关键字

names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)

range(101)就可以生成0-100的整数序列,计算如下:

sum = 0
for x in range(101):
    sum = sum + x
print(sum)

 

Python学习笔记(一)

Python是非常流行的脚本语言,能够用非常简洁的代码完成复杂的逻辑。出于一下几个原因我决定开始学习Python:

  1. 直接原因是公司的网站用Django框架
  2. 间接原因是由于同时还肩负着公司的运维,经常需要使用脚本
  3. 个人原因也需要掌握一门脚本语言。之前只用shell写脚本有些吃力

于是就这样开始了~

安装Python3

Python有两个主要版本:2.x和3.x。既然有新的版本那就从新版本入手好了,于是决定学习Python3。

Ubuntu14.04下自带了Python3.4,但是直接使用python命令调用的是Python2.7:

root@localhost:~# python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

使用python3命令时才会调用3.4版本的python:

root@localhost:/usr/bin# python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

使用以下步骤将默认的python版本切换为python3。

在用户目录下新建.bash_alias文件:

cd ~
vi .bash_alias

向其中写入以下内容:

alias python=python3

执行下面命令完成切换:

source ~/.bash_aliases

再使用python命令时版本已经切换成了python3:

root@localhost:~# python
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Hello World

创建.py文件,写入一下内容:

print('hello, world')

执行

# python helloworld.py
hello, world