一.版本问题
python2与python3是目前主要的两个版本。
python3.0版本较之前的有很大变动,而且不向下兼容。
Python 2.7作为一个过渡版本,基本使用了Python 2.x的语法和库,同时考虑了向Python 3.0的迁移。即2.7版本兼容2.x和3.0的语法
Python 2.7保持了对之前版本的全兼容,而且还包含了Python 3.0的新玩意(一些新特性需要通过“from __future__ import”来启用)。
如果想要在python2.7中使用:print(‘error happens!‘, file=sys.stderr)这样的语句,就需写上“ from __future__ import print_function”
基于早期Python版本而能正常运行于Python 2.7并无警告的程序可以通过一个2 to 3的转换工具无缝迁移到Python 3.0。
部分函数和语句的改变
最引人注意的改变是print语句没有了,取而代之的是print函数
同样的还有exec语句,已经改为exec()函数。去除了<>,全部改用!=。
在python2.x版本中
#!/usr/bin/env python
# 或者上句写: #!/usr/bin/python
print "Hello, world!"
或者:
import sys
sys.stdout.write("Hello, world\n")
在python3.x中
print(‘Hello world!‘)
用迭代器来替代列表
一些知名的API将不再返回列表。
而字典的dict.iterkeys()、dict.itervalues()和dict.iteritems()方法将会移除,而你可以使用.keys()、.values()和.items(),它们会返回更轻量级的、类似于集合的容器对象,而不是返回一个列表来复制键值。
这样做的优点是,可以直接在键和条目上进行集合操作,而不需要再复制一次。
整型数
移除了含糊的除法符号(‘/‘),而只返回浮点数。
在以前的版本中,如果参数是int或者是long的话,就会返回相除后结果的向下取整(floor),而如果参数是float或者是complex的话,那么就会返回相除后结果的一个恰当的近似。
在2.6版本中可以通过from __future__ import division来启用这项特性。
二.python2 to python3 问题
1.print 语句
2.x 3.x 说明
① print print() # 输出一个空白行
② print 1 print(1) # 输出一个单独的值
③ print 1, 2 print(1, 2) # 输出多个值,以空格分割
④ print 1, 2, print(1, 2, end=‘ ‘) # 输出时取消在末尾输出回车符。
⑤ print >>sys.stderr, 1, 2 print(1, 2, file=sys.stderr) # 把输出重定向到一个管道
2.被重命名或者重新组织的模块
1)http
在Python 3里,几个相关的HTTP模块被组合成一个单独的包,即http。
2.x 3.x
① import httplib import http.client # http.client 模块实现了一个底层的库,可以用来请求HTTP资源,解析HTTP响应。
② import Cookie import http.cookies # http.cookies 模块提供一个蟒样的(Pythonic)接口来获取通过HTTP头部(HTTP header)Set-Cookie发送的cookies
③ import cookielib import http.cookiejar # 常用的流行的浏览器会把cookies以文件形式存放在磁盘上,http.cookiejar 模块可以操作这些文件。
④ import BaseHTTPServer import http.server # http.server 模块实现了一个基本的HTTP服务器
import SimpleHTTPServer
import CGIHttpServer
2)urllib
Python 2有一些用来分析,编码和获取URL的模块,但是这些模块就像老鼠窝一样相互重叠。在Python 3里,这些模块被重构、组合成了一个单独的包,即urllib。
2.x 3.x
① import urllib import urllib.request, urllib.parse, urllib.error
② import urllib2 import urllib.request, urllib.error
③ import urlparse import urllib.parse
④ import robotparser import urllib.robotparser
⑤ from urllib import FancyURLopener from urllib.request import FancyURLopener
from urllib import urlencode from urllib.parse import urlencode
⑥ from urllib2 import Request from urllib.request import Request
from urllib2 import HTTPError from urllib.error import HTTPError
以前,Python 2里的 urllib 模块有各种各样的函数,包括用来获取数据的 urlopen(),还有用来将URL分割成其组成部分的 splittype(), splithost()和 splituser()函数。
在python3的 urllib 包里,这些函数被组织得更有逻辑性。2to3将会修改这些函数的调用以适应新的命名方案。
在Python 3里,以前的 urllib2 模块被并入了 urllib 包。同时,以 urllib2 里各种你最喜爱的东西将会一个不缺地出现在Python 3的 urllib 模块里,比如 build_opener()方法, Request 对象, HTTPBasicAuthHandler 和 friends 。
Python 3里的 urllib.parse 模块包含了原来Python 2里 urlparse 模块所有的解析函数。
urllib.robotparse 模块解析 robots.txt 文件。
处理HTTP重定向和其他状态码的 FancyURLopener 类在Python 3里的 urllib.request 模块里依然有效。 urlencode()函数已经被转移到了 urllib.parse 里。
Request 对象在 urllib.request 里依然有效,但是像HTTPError这样的常量已经被转移到了 urllib.error 里。
3)dbm
所有的DBM克隆(DBM clone)现在在单独的一个包里,即dbm。如果你需要其中某个特定的变体,比如GNU DBM,你可以导入dbm包中合适的模块。
2.x 3.x
① import dbm import dbm.ndbm
② import gdbm import dbm.gnu
③ import dbhash import dbm.bsd
④ import dumbdbm import dbm.dumb
⑤ import anydbm import dbm
import whichdb
4)xmlrpc
XML-RPC是一个通过HTTP协议执行远程RPC调用的轻重级方法。一些XML-RPC客户端和XML-RPC服务端的实现库现在被组合到了独立的包,即xmlrpc。
2.x 3.x
① import xmlrpclib import xmlrpc.client
② import DocXMLRPCServer import xmlrpc.server
import SimpleXMLRPCServer
5)其他模块
2.x 3.x
① try: import io
import cStringIO as StringIO # 在Python 2里,你通常会这样做,首先尝试把cStringIO导入作为StringIO的替代,如果失败了,再导入StringIO。
except ImportError: # 不要在Python 3里这样做;io模块会帮你处理好这件事情。它会找出可用的最快实现方法,然后自动使用它。
import StringIO
② try: import pickle
import cPickle as pickle # 在Python 2里,导入最快的pickle实现也与上边 io 相似。在Python 3里,pickle模块会自动为你处理,所以不要再这样做。
except ImportError:
import pickle
③ import __builtin__ import builtins
④ import copy_reg import copyreg # copyreg模块为用C语言定义的用户自定义类型添加了pickle模块的支持。
⑤ import Queue import queue # queue模块实现一个生产者消费者队列(multi-producer, multi-consumer queue)。
⑥ import SocketServer import socketserver # socketserver模块为实现各种socket server提供了通用基础类。
⑦ import ConfigParser import configparser # configparser模块用来解析INI-style配置文件。
⑧ import repr import reprlib # reprlib 模块重新实现了内置函数 repr(),并添加了对字符串表示被截断前长度的控制。
⑨ import commands import subprocess # subprocess 模块允许你创建子进程,连接到他们的管道,然后获取他们的返回值。
builtins模块包含了在整个Python语言里都会使用的全局函数,类和常量。重新定义builtins模块里的某个函数意味着在每处都重定义了这个全局函数。这听起来很强大,但是同时也是很可怕的。
三.关键字
and assert break class continue def elif else except exec
eval finally for from global if import in is lambda not
nonlocal or pass print raise return try with while yield
False None True
注释
无论是行注释还是段注释,均以“#”来注释。
段注释,经常采用多行字符串的写法,即三个单引号或者三个双引号括起来。
如果需要在代码中使用中文注释,必须在python文件的最前面加上如下注释说明:
# -* - coding: UTF-8 -* -
如下注释用于指定解释器(必须在python文件的最前面加上)
#! /usr/bin/python
四.数字类型
共4种: 整数(int)、长整数(long)、浮点数(float)和复数(complex)。
1.整数,如:2
2.长整数,如:22L # 长整数不过是大一些的整数。Python 3已经取消这种类型,被int取代了。
3.浮点数,如:3.23 和 52.3E-4 # E标记表示10的幂。在这里,52.3E-4表示52.3 * 10-4。
4.复数,如:(-5+4j) 和 (2.3-4.6j)
在Python 2和Python 3的变化:
1.八进制(octal)数:
Python 2: x = 0755 # 0开头
Python 3: x = 0o755 # 0o开头
2.long 类型
Python 2有为非浮点数准备的 int 和 long 类型。 int 类型的最大值不能超过 sys.maxint,而且这个最大值是平台相关的。
整数可以通过在数字的末尾附上一个L来定义长整型,显然,它比 int 类型表示的数字范围更大。
Python 3里,只有一种整数类型 int,大多数情况下,它很像Python 2里的长整型。
由于已经不存在两种类型的整数,所以就没有必要使用特殊的语法去区别他们。
由于 long 类型在Python 3的取消,引起以下改变
Python 2 Python 3 说明
① x = 1000000000000L x = 1000000000000 # 十进制的普通整数
② x = 0xFFFFFFFFFFFFL x = 0xFFFFFFFFFFFF # 十六进制的普通整数
③ long(x) int(x) # long()函数没有了。可以使用int()函数强制转换一个变量到整型。
④ type(x) is long type(x) is int # 检查一个变量是否是整型
⑤ isinstance(x, long) isinstance(x, int) # 也可以使用 isinstance()函数来检查数据类型
3.sys.maxint(sys.maxsize)
由于长整型和整型被整合在一起了, sys.maxint常量不再精确。
因为这个值对于检测特定平台的能力还是有用处的,所以它被Python 3保留,并且重命名为 sys.maxsize。
Python 2 Python 3
① from sys import maxint from sys import maxsize # maxint变成了maxsize。
② a_function(sys.maxint) a_function(sys.maxsize) # 所有的sys.maxint都变成了sys.maxsize。
int 是 types.IntType 的代名词
print(id(int)) # 打印如:505210872
import types;print(id(types.IntType)) # 打印如:505210872
高精度的数值类型
float 精度不够高,有时候需要更高精度的类型 decimal
python 支持的是:
from decimal import Decimal
a = Decimal(‘5555555555551111111.11100002225555‘)
b = Decimal(‘-1.01‘) # Decimal 构造时,只能用字符串、int、long,不能用 float 类型
print a + 55
print a + b # Decimal 类型运算时,只能跟 Decimal、int、long 类型,不能跟 float 类型一起运算
五.标识符的命名
变量是标识符的例子。 标识符 是用来标识 某样东西 的名字。在命名标识符的时候,你要遵循这些规则:
1.标识符的第一个字符必须是字母表中的字母(大写或小写)或者一个下划线(‘_’)。
2.标识符名称的其他部分可以由字母(大写或小写)、下划线(‘_’)或数字(0-9)组成。
3.标识符名称是对大小写敏感的。例如,myname和myName不是一个标识符。
有效 标识符名称的例子有i、__my_name、name_23和a1b2_c3。
无效 标识符名称的例子有2things、this is spaced out和my-name。
六.逻辑行与物理行
物理行是在编写程序时文本的一行。逻辑行是程序的一个语句。
Python假定每个 物理行 对应一个 逻辑行 。 他希望每行都只使用一个语句,这样使得代码更加易读。
1. 如果你想要在一个物理行中使用多于一个逻辑行,那么你需要使用分号(;)来特别地标明这种用法。
分号表示一个逻辑行/语句的结束。
如: i = 5; print i; # 强烈建议你坚持在每个物理行只写一句逻辑行。 让程序见不到分号,而更容易阅读。
2. 明确的行连接
在多个物理行中写一个逻辑行,行结尾用反斜杠标明
如: s = ‘This is a string. \
This continues the string.‘
# 上面这两行是一个逻辑行,打印是: This is a string. This continues the string.
print \
i
# 上面这两行也是一个逻辑行, 等同于: print i
3. 暗示的行连接
在多个物理行中写一个逻辑行,行结尾不需要使用反斜杠标明。
这种情况出现在逻辑行中使用了圆括号、方括号或花括号的时候。
4. 缩进
行首的空白是重要的。在逻辑行首的空白(空格和tab符)用来决定逻辑行的缩进层次,从而用来决定语句的分组。
同一层次的语句必须有相同的缩进。每一组这样的语句称为一个块。
不要混合使用tab符和空格来缩进,因为这在跨越不同的平台的时候,无法正常工作。强烈建议只使用一种风格来缩进。
七.语法规则
1.缩进规则
一个模块的界限,完全是由每行的首字符在这一行的位置来决定的(而不是花括号{})。这一点曾经引起过争议。
不过不可否认的是,通过强制程序员们缩进,Python确实使得程序更加清晰和美观。
在逻辑行首的空白(空格和tab)用来决定逻辑行的缩进层次,从而用来决定语句的分组。错误的缩进会引发错误。
注意: 强制缩进的问题,最常见的情况是tab符和空格的混用会导致错误,而这是用肉眼无法分别的。
2.变量没有类型
使用变量时只需要给它们赋值。 不需要声明或定义数据类型。
3.单语句块
如果你的语句块只包含一句语句,那么你可以在条件语句或循环语句的同一行指明它。如: if 1!=2: print(‘Yes‘)
强烈建议不要使用这种缩略方法。这会破坏Python清晰美观的代码风格,违背设计者的初衷。
如果是在Python解释器输入,它的把提示符会改变为...以表示语句还没有结束。这时按回车键用来确认语句已经完整了。然后,Python完成整个语句的执行,并且返回原来的提示符来等待下一句输入。
八.变量
1.python中的变量不需要声明,变量的赋值操作即使变量声明和定义的过程。
2.python中一次新的赋值,将创建一个新的变量。即使变量的名称相同,变量的标识并不相同。
用id()函数可以获取变量标识:
x = 1
print id(x)
x = 2
print id(x)
3 如果变量没有赋值,则python认为该变量不存在
4 在函数之外定义的变量都可以称为全局变量。全局变量可以被文件内部的任何函数和外部文件访问。
5 全局变量建议在文件的开头定义。
6 也可以把全局变量放到一个专门的文件中,然后通过 import 来引用
九.对象
Python 将 "一切皆对象" 贯彻得非常彻底,不区分什么 "值类型" 和 "引用类型"。所谓变量,实质就是一个通用类型指针 (PyObject*),它仅仅负责指路,至于目标是谁,一概不管。
Python Object 对象的自身结构了。任何对象,就算一个最简单的整数,它的头部都会拥有 2 个特殊的附加信息,分别是:"引用计数" 和 "类型 (type) 指针" 。前者指示 GC 何时回收,而后者标明了对象的身份,如此我们就可以在运行期动态执行对象成员调用。
连同附加头,一个 "普通" 的整数起码得 12 字节:
a = 8; import sys; print(sys.getsizeof(a)) # 打印: 12 (python3.2中,打印的是14)
print(sys.getsizeof(None)) # 打印: 8
控制台输入
使用 raw_input()函数 或者 input()函数 能够很方便的控从制台读入数据,得到的是字符串。
Python2.x时,raw_input()和 input()的区别:
当输入为纯数字时:input()返回的是数值类型,如:int,float; raw_input()返回的是字符串类型
input()会计算在字符串中的数字表达式,而 raw_input()不会。如输入“57+3”: input()得到整数60,raw_input()得到字符串‘57+3‘
注:Python3.0将 raw_input()函数去除了,而用 input() 取代它的功能。另外,input()获取的字符串会包括结尾的换行符。
例:(此处是Python2.6的写法,3.x时应该把 raw_input() 改成 input())
1.输入字符串
nID = raw_input("Input your id plz:\n"); print(‘your id is %s‘ % (nID))
2.输入整数
nAge = int(raw_input("input your age plz:\n")); print(‘your age is %d\n‘ % nAge)
3.输入浮点型
fWeight = float(raw_input("input your weight:\n")); print(‘your weight is %f‘ % fWeight)
4.输入16进制数据
nHex = int(raw_input(‘input hex value(like 0x20):\n‘),16); print(‘nHex = %x,nOct = %d\n‘ %(nHex,nHex))
5.输入8进制数据
nOct = int(raw_input(‘input oct value(like 020):\n‘),8); print(‘nOct = %o,nDec = %d\n‘ % (nOct,nOct))
注:打印字符串时,“%”作为特殊符号,两个百分号才能打印出一个百分号
十.Python 2 与 Python 3 的比较
Python 2 Python 3
① raw_input() input() # 最简单的形式,raw_input()被替换成input()。
② raw_input(‘prompt‘) input(‘prompt‘) # 可以指定一个提示符作为参数
③ input() eval(input()) # 如果想要请求用户输入一个Python表达式,计算结果
1.print 会遇到重定向的问题
需要把 print 换成 sys.stderr.write(...) 试试
2. 符号“>>”用来重定向输出,可以输出到文件
下面这个例子将输出重定向到标准错误输出:
import sys
print >> sys.stderr, ‘Fatal error: invalid input!‘
下面是一个将输出重定向到日志文件的例子:
logfile = open(‘/tmp/mylog.txt‘, ‘a‘)
print >> logfile, ‘Fatal error: invalid input!‘
logfile.close()