Python是一种解释型动态强类型语言,支持过程式,面向对象程序设计范式和部分函数式语言特性。
弱类型与动态类型是从不同角度定义的概念:弱类型倾向于容忍隐式类型转换, 即类型之间的界限不明显.动态类型可以理解为引用没有类型而值有类型, 即同一个引用可以动态的指向不同类型的值.我们熟悉的C属于静态弱类型语言.Python倾向于不容忍隐式类型转换, 大多数情景下可以将Python归为动态强类型语言.
Python具有具有较高的开发效率,但执行效率较低。
Python支持在交互式和脚本两种编程模式,Python脚本文件通常保存为.py格式.
>>>
为Python解释器的命令提示符:
>>> print(“Hello World!”)Hello World!
“#”是Python中行注释的引导符:
# This is a piece of Python comment
Python使用分号;
或换行标志语句结束, 允许使用\
进行折行.
Python标识符区分大小写,以字母或_
开头, 后续字符可以为数字,字母或_
.
Python允许以单一下划线(_
)作为标识符,但它一般在解释器环境下代表上一条指令计算的结果.
以单个下划线(_
)或以双下划线(__
)开头的标识符在Python中一般有特殊含义。
很多Python内置对象采用下划线开头的命名方式,除非重写这些内容否则不要使用这种风格的命名。
Python采用引用访问对象,Python中一切(包括内置类型及其字面值)都是对象。对象在使用前无需声明,直接使用一个新的标识符表明新建对象。
global obj
语句声明obj为同名的全局变量,在使用obj时将引用全局对象而不会建立局部对象。
del obj
指令可以删除特定的对象。None
是Python中代表空值的关键字。
Python使用”=”作为赋值运算符,可以连续赋值,但不能理解为”=”有返回值。
>>> x=a=2>>>x < a = 2File "", line 1SyntaxError: can't assign to comparison>>> x < (a = 2)File " ", line 1x < (a = 2) ^SyntaxError: invalid syntax
Python使用与C相同的关系运算符,包括==
与!=
。
数据类型
bool
Python中的bool类型包含”True”和“False”两个取值(注意大小写)。
Python提供了3个逻辑运算符and
,or
和not
,它们都具有短路特性。
int
Python中int的容量只取决于机器运行内存的大小与字长无关。
算术运算
Python中的int支持C中所有的算术运算(+
,-
,*
,/
,%
和位运算~
,^
位异或,&
,|
),并定义了表示乘方运算的新运算符**
//
整数上的除法运算,Python的int/int运算不再具有截断的特性,int//int则具有截断的特性(不是四舍五入)
所有双目算术运算符均具有对应的复合赋值运算符(+=,**=,//=,^=...),但是Python删除了自增自减运算符。
进制与转换
int默认采用十进制计数,可以通过显式引导符指定通过二进制,八进制或十六进制表示。
>>>789 #decimal 789>>>0b1100010101 #binary 789>>>0B1100010101 789>>>0o1425 #octonary 789>>>0x315 #hexadecimal 789
引导符中的字母是大小写不敏感的。Python中提供了一系列函数用于进制和与int有关的类型转换。
>>>bin(789) ‘0b1100010101’>>>oct(789) ‘0o1425’>>>hex(789) ‘0x315’
上述函数可以将int值转换对应的带有进制引导符的字符串。
>>>int(x)
将对象x转换int值,若失败则抛出ValueError异常;若未定义转换规则则抛出TypeError异常。对于浮点数则采取截断的方式进行转换.
Python提供了round(x,n)函数对浮点数进行保留n位小数的四舍五入近似。
>>>int(str,base)
将使用字符串表示的int(不带进制引导符)转换为0~32进制数,以无引导的int对象表示。
>>>int(“315”,32) 3109
float
float是Python中内置的浮点数类型,采用双精度浮点表示。它的语法与int类型类似.
Python支持采用e或E表示的浮点字面值。
int//int采用截断的方式取整,而float//float仍采用截断取整但保留一位小数。
>>>16//91>>>16.0//9.01.0
complex
complex类型是Python内置的复数类型, 虚数单位用字母j表示.
一个complex字面值可以写作1+2j的形式,注意1+1j和1-1j不能写作1+j和1-j,实部为0时可以省略.
实部与虚部作为对象的属性出现,以real和imag表示.
>>>1+2j.real1.0>>>(1+2j).imag2.0>>>(1+2j).real1.0
complex类型不能使用//、%运算以及涉及这些运算的库函数.
math模块中不支持复数运算,若需复数支持则使用cmath模块.
流程控制
if
if time > 20: print('good evening')elif time > 12: print('good afternoon')else: print('good morning')
每个条件后面要使用冒号(:),表示接下来是满足条件后要执行的语句块
使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块
在Python中没有switch – case语句
while
示例:
a = 233while a: a -= 1else: print(a)
在condition为真时执行循环,最后一次循环后执行else之后的内容。
for
for循环可以遍历包括线性容器和集合容器在内的所有容器:
>>> for i in ("C","C++","Qt","Java","Matlab","Python"):... print(i)...CC++QtJavaMatlabPython
range(begin,end,step)函数可以生成一段左闭右开的数字序列[begin,end):
>>> for i in range(1,101):... s += i... else:... s...5050
break,continue
break语句用于强行跳出循环,break语句跳出循环后不执行else后的语句。
continue语句用于强制结束本次循环体执行。
pass
pass语句用于占位:
def func(): pass
异常
try: statementsexcept except_class as variable: statementselse: statementsfinally: statements
Python 使用 raise 语句抛出一个指定的异常:
raise NameError('HiThere')
首先执行try块,若发生异常则由响应的except块接收,若无异常发生则执行else块,无论是否有异常抛出finally块都将被执行。
except块按照定义顺序进行匹配,except_class指定匹配的异常类,variable为保存异常信息的类对象。
若无except_class则可以匹配任意异常,通常作为最后一个except块捕获其它类型的异常。
示例:
>>> def this_fails(): x = 1/0>>> try: this_fails() except ZeroDivisionError as err: print('Handling run-time error:', err) except: print('Unkown error') Handling run-time error: int division or modulo by zero
用户自定义异常需要直接或间接地继承Exception类:
>>> class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value)>>> try: raise MyError(2*2) except MyError as e: print('My exception occurred, value:', e.value)My exception occurred, value: 4>>> raise MyError('oops!')Traceback (most recent call last):File "", line 1, in ?__main__.MyError: 'oops!'
在try语句使用finally块释放资源非常不便, python2中引入了上下文管理.
with open(file, 'r') as f: for line in f: print(line)
上述语句可以自动打开文件, 当控制流离开with...as代码块后自动关闭文件.
with EXPR as VAR
语句会先计算EXPR并将返回值保存在变量VAR中.
控制流进入代码块时会执行VAR.__enter__()
方法, 退出代码块时执行VAR.__exit__()
方法.
class FileContext: def __init__(self, filename): self.filename = filename self.session = None def __enter__(self): self.session = open(filename, 'r') return self.session def __close__(self): self.session.close()with FileContext('1.txt') as f: for line in f: print(line)
IO
Console IO
>>> print('a', 1)('a', 1)>>> print([1,2,3,4])[1, 2, 3, 4]>>> print('%s is lagger than %d' % ('5', 1))5 is lagger than 1
input
>>> a = input('please input a:\n')please input a:1>>> a1
File IO
open()
open() 将会返回一个 file 对象:
open(filename, mode)
filename参数为要打开的文件名.
mode指定打开方式:
'r' 只读, mode的默认值
'w' 只写, 原有内容将清空
'a' 用于追加文件内容,初始插入位置为末尾
'r+' 同时用于读写
示例:
>>> f = open('/tmp/workfile', 'w')
使用os.path.getsize(f.name)
可以得到文件的字节数, 文件还是一个可迭代对象:
for line in f: print(line)
f.read()
文件对象方法f.read(size), 可以读取一定数目的数据, 然后作为字符串或字节对象返回。
size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。
>>> f.read()'This is the entire file.\n'
f.readline()
f.readline() 会从文件中读取单独的一行。换行符为 '\n'.
f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。
>>> f.readline()'This is the first line of the file.\n'>>> f.readline()'Second line of the file\n'
迭代一个文件对象然后读取每行:
>>> for line in f:... print(line, end='')...
f.readlines()
f.readlines() 将返回该文件中包含的所有行.
如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。
>>> f.readlines()['This is the first line of the file.\n', 'Second line of the file\n']
f.write()
f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。
>>> f.write('This is a test\n')15
f.tell()
返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。
f.seek()
如果要改变文件当前的位置, 可以使用 f.seek(offset, from) 函数.
from 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾:
seek(x,0) #从起始位置即文件首行首字符开始移动 x 个字符seek(x,1) #表示从当前位置往后移动x个字符seek(-x,2) #表示从文件的结尾往前移动x个字符
from的默认值为0,即文件开头。
f.close()
关闭文件。
模块与包
模块
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py
模块可以被别的程序引入,以使用该模块中的对象。
这也是使用Python库的方法:
import sysprint('命令行参数如下:')for i in sys.argv: print(i)print('/n/nThe PYTHONPATH is', sys.path, '/n')
在解释器的当前目录或者sys.path中的一个目录里面来创建一个.py的文件,其它文件可以将该文件作为模块导入
模块除了方法和类定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入或reload时才会被执行。
如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__
属性来使该程序块仅在该模块自身运行时执行。
if __name__ == '__main__': print('myself')else: print('another model')
包
包是采用目录结构提供命名空间管理模块的方式,在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
目录只有包含一个叫做 __init__.py
的文件才会被认作是一个包,主要是为了避免一些频繁使用的名字影响搜索路径中的有效模块。
Python提供了两种导入语法:
import packages.module
from packages import module
如:
import PyQt4
它必须使用全名去访问:
app = PyQt4.QtGui.QApplication(sys.argv)
或者:
from PyQt4.QtGui import QApplication
它不必使用全名去访问:
app = QApplication(sys.argv)
它也可以只导入一个函数,类或各种对象,例如:
from PyQt4.QtCore import QObject, SIGNAL
它可以选择导入一个包下的所有模块:
from sys import *
Python中一切都是对象, 模块和包都是module对象.
因为有些文件系统的原因,它工作的并不好(如win系fs不区分大小写),所以Python规定:
如果包定义文件__init__.py
存在一个叫做 __all__
的列表变量,那么在使用 from package import *
的时候就把这个列表中的所有名字作为包内容导入。