python基础入门教程
以 #! 开头的称为组织行,这行告诉你的Linux/Unix系统当你执行你的程序的时候,它应该运行哪个解释器。例如:#!/usr/bin/python
以 # 开头的称为注释行。
Python 源文件通常用.py 扩展名。当源文件被解释器加载或者显式地进行字节码编译的时候会被编译成字节码。由于调用解释器的方式不同,源文件会被编译成带有.pyc 或.pyo 扩展名的文件。
一、基本输入输出
print 语句调用str()函数显示对象,而交互式解释器则调用repr()函数来显示对象。
从用户那里得到数据输入的最容易的方法是使用raw_input()内建函数。它读取标准输入,并将读取到的数据赋值给指定的变量。
从标准输入读取一个字符串并自动删除串尾的换行字符。如果用入键入了 EOF 字符(Unix: Ctrl+D, Windows: Ctrl+Z+回车), 则引发 EOFError, 在 Unix 平台, 只要可用,就使用 GNU readline 库。
如果提供提示字符串参数,则显示该字符串并自动删去字符串末尾的换行字符。
在学习 Python 的过程中,如果需要得到一个生疏函数的帮助,只需要对它调用内建函数help()。通过用函数名作为 help()的参数就能得到相应的帮助信息。
二、变量和表达式
>>> 1 + 1 2 >>> print 'hello world' hello world >>> x = 1 >>> y = 2 >>> x + y 3
Python是强类型语言,无法根据上下文自动解析转换成合适的类型,变量必须先声明类型后才能使用。
Python是一种动态语言,在程序运行过程中,同 一个变量名在运行的不同阶段可以代表不同形式的值(整型,浮点,列表,元组),变量名只是各种数据及对象的引用。C语言中的变量名是用来存放结果的内存片段。
5种基本数值类型:int(有符号整数)、long(长整数)、bool(布尔值)、float(浮点值)、complex(复数)。
还有第六种数字类型,decimal,用于十进制浮点数。不过它并不是内建类型,必须先导入 decimal 模块才可以使用这种数值类型。
同一个变量名在运行的不同阶段可以代表不同形式的值(整型,浮点,列表,元组)。变量名只是各种数据及对象的引用。C语言中的变量名是用来存放结果的内存片段。
python 不支持自增自减操作符++,--,++i,其实是+(+i)的意思
运算符:+ - * / // % **
运算符与表达式:基本上与其它语言相类似,只是有以下几点不同。
x*y # 乘法,2 * 3得到6,'la' * 3得到'lalala'。 x**y # 幂运算,返回 x 的 y 次幂。 x/y # x 除以 y,4/3得到1(整数的除法得到整数结果)。4.0/3或4/3.0得到1.3333333333333333。 x//y # 取整除,返回商的整数部分,4 // 3.0得到1.0。地板除在任何时候都会将小数部分舍为0 -x # 改变x的符号位
比较运算符:< <= > >= == != <>
逻辑运算符:and or not
python 整数支持标准位运算:取反(~),按位 与(&), 或(|) 及 异或(^) 及左移(<<)和右移(>>)
& 符号,x & y ,会将两个十进制数在二进制下进行与运算 | 符号,x | y ,会将两个十进制数在二进制下进行或运算 ^ 符号,x ^ y ,会将两个十进制数在二进制下进行异或运算 << 符号,x << y 左移操作,最右边用 0 填充 >> 符号,x >> y 右移操作,最左边用 0 填充 ~ 符号,~x ,按位取反操作,将 x 在二进制下的每一位取反
括号在python语言中不是必须存在的,不过为了可读性,使用括号总是值得的。
避免用下划线作为变量名的开始:因为下划线对解释器有特殊的意义,而且是内建标识符所使用的符号,建议避免用下划线作为变量名的开始。一般来讲,变量名_xxx 被看作是“私有的”,在模块或类外不可以使用。当变量是私有的时候,用_xxx 来表示变量是很好的习惯。因为变量名__xxx__对 python 来说有特殊含义,对于普通的变量应当避免这种命名风格。
三、基本控制语句
控制流语句:通过使用or,and,not关键字可以建立任意的条件表达式
if-elif-else:(Python 没有 switch-case 语句,可以通过 if 语句配合字典完成同样的工作)
if something == 1: doSomething1() elif something == 2: doSomething2() else: pass # 表示一个空的块或者是空的主体,使用pass语句 while-else: while something: doSomething1() else: doSomething2() for-else: for i in range(1, 10, 2): # i 值从 1 到 10,步长为2 print i else: print 'The for loop is over'
break 和 continue:用于中断和继续循环。
for i in range(1,5): print "2 to the %d power is %d" % (i,2**i) a=range(5,1,-1) # a=[5,4,3,2] s="hello world" for c in s: # 打印每个字符 print c
range(i,j)函数建立一个整数序列,从第i个到第j个(不包括j)。若第一个省略则为0。函数的第三个参数是步进值
range()函数在内存中建立一个列表,当需要一个很大的列表时候,这个占内存且耗时间,为了克服这个缺点,python提供了xrange(),xrange()函数只在需要的时候才临时计算提供值,大大节省了内存。
三元操作符:X if C else Y (C是条件表达式; X是C为 True 时的结果, Y是C为 False 时的结果)
四、文件
f=open("foo.txt") line=f.readline() while line: print line, line=f.readline() #读取一行,包括换行符'\n',读到文件末尾,返回空字符串 f.close()
f=open("out.txt","w") year=1 money=1000 while year<=5: money=money*(1+0.05) f.write("%3d %0.2f\n" % (year,money)) # print>>f,"%3d %0.2f" % (year,money) year+=1 f.close() for line in f.xreadlines(): # Do something with line
五、字符串
字符串:单引号(‘)和双引号(")的作用相同,只能创建单行字符串。转义符是(\)。
三引号(如:'''或者""")之间的一切都是字符串的内容。
自然字符串:在字符串前加R(或r)指示某些不需要如转义符那样的特别处理的字符串,如:print R“Hello\n World”,将直接输出“Hello\n World”而不会出现换行的情况。
a="hello world" b=a[0,5] # b="hello" c=a+" I love you" # c="hello world I love you" s="The value of x is "+ str(x)
字符串是不可变对象,函数返回是一个新的对象。
常见函数:
split(sep=None, maxsplit=-1) # 以sep来分割字符串 strip([chars]) # 去除首末两端的字符, 默认是 \r,\n," " join(iterable) # 将iterable内的元素拼接成字符串,如','.join(['leet', 'code'])="leet,code" replace(old, new[, count]) # 字符串替换, old to new count(sub[, start[, end]]) # 统计子字符串sub的个数 startswith(prefix[, start[, end]]) # 以prefix开始的字符串 endswith(suffix[, start[, end]]) # 以suffix结束的字符串 cs in chrs: # chrs 中包含 cs
获得子串: s[i:j],返回 s 从i到j(不包括j)之间的子串。若i省略则i=0,若j省略则j=len(s)-1
str() repr() 函数或者向后的引号(`)可以将其他类型的数据转换为字符串。
Unicode字符串:在字符串前加U(或u)。如 a=u'hello',每个字符用16位来表示 "hello" 'world'会被自动连接为一个字符串"helloworld" ,"s1" u"s2"就会产生u"s1s2"
字符串、Unicode字符串及tuple是不可变的序列。
str()和 unicode()函数都是工厂函数,就是说产生所对应的类型的对象。它们接受一个任意类型的对象,然后创建该对象的可打印的或者 Unicode 的字符串表示。
chr()函数用一个范围在 range(256)内的(就是0到255)整数做参数,返回一个对应的字符。unichr()跟它一样,只不过返回的是 Unicode 字符,这个从 Python2.0才加入的 unichr()的参数范围依赖于你的Python 是如何被编译的。
ord()函数是 chr()函数(对于 8 位的 ASCII 字符串)或 unichr()函数(对于 Unicode 对象)的配对函数,它以一个字符(长度为 1 的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode数值。
六、列表和元组(list & tuple & deque)
列表和元组是任意对象的序列,支持的常用操作:
len()
append()
insert(index,aMember)
list[index]=aNewMember
列表是可变的序列,允许插入,删除,替换元素等操作。
可变序列支持的操作:
s[i]=v s[i:j]=t # t要是个序列 del s[i] del s[i:j] list[first:last] # 不包含下标为last的子列表
那些可以改变对象值的可变对象的方法是没有返回值的:在使用可变对象的方法如 sort(),extend()和 reverse()的时候要注意,这些操作会在列表中原地执行操作,也就是说现有的列表内容会被改变,但是没有返回值!
与之相反,字符串方法确实有返回值:字符串是不可变的,不可变对象的方法是不能改变它们的值的,所以它们必须返回一个新的对象。
list常见函数:
lst.sort(*, key=None, reverse=False) lst.append(val) # 也可以 lst = lst + [val] lst.clear() # 清空列表 lst.count(val) # val个数 lst.pop(val=lst[-1]) # (默认)从末端移除一个值 lst.remove(val) # 移除 val lst.reverse() # 反转 lst.insert(i, val) # 在 i 处插入 val
一个元素的元组:a=(12,) #注意一定要个额外的逗号!
对于tuple中的元素,不可以修改,也不可以添加。
修改tuple内部可变对象:
t = (['xyz', 123], 23, -103.4) t[0][1] = ['abc', 'def'] t # (['xyz', ['abc', 'def']], 23, -103.4)
双端队列 deque 常见函数
queue = deque([iterable[, maxlen]]) queue.append(val) # 往右边添加一个元素 queue.appendleft(val) # 往左边添加一个元素 queue.clear() # 清空队列 queue.count(val) # 返回指定元素的出现次数 queue.insert(val[, start[, stop]]) # 在指定位置插入元素 queue.pop() # 获取最右边一个元素,并在队列中删除 queue.popleft() # 获取最左边一个元素,并在队列中删除 queue.reverse() # 队列反转 queue.remove(val) # 删除指定元素 queue.rotate(n=1) # 把右边元素放到左边
七、字典与集合(map & set & heapq)
字典就是一个关联数组(或称为哈希表),是一个通过关键字索引的对象集合。
使用{}来创建一个字典
a={ "username":"loo" "home":"/home/loo" "uid":500 } u=a["username"] #访问 a["username"]="lu" #修改 a["shell"]="/usr/bin/tcsh" #添加 del a["shell"] #删除 len(a) #元素个数 a[("loo",123)]="abc"
字典的key是不能修改的对象(比如数字和tuple)。
每个键只能对应一个项。当有键发生冲突(即,字典键重复赋值),取最后(最近)的赋值。
键必须是可哈希的对象。像列表和字典这样的可变类型,由于它们不是可哈希的,所以不能作为键。
用元组做有效的键,必须要加限制:元组中只包括像数字和字符串这样的不可变参数,才可以作为字典中有效的键。
列表和字典可以分别用他们自己的工厂方法 list() 和 dict() 创建 。
字典 dict 常见函数:
d = defaultdict(lambda : value) # 取到不存在的值时不会报错,用{}时、需要设置get的default值 pop(key[, default]) # 通过键去删除键值对(若没有该键则返回default(没有设置default则报错)) setdefault(key[, default]) # 设置默认值 update([other]) # 批量添加 get(key[, default]) # 通过键获取值(若没有该键可设置默认值, 预防报错) clear() # 清空字典 keys() # 将字典的键组成新的可迭代对象 values() # 将字典中的值组成新的可迭代对象 items() # 将字典的键值对凑成一个个元组, 组成新的可迭代对象 dict1 = dict2 #两个字典完全相等,滑窗时可用
集合(set)有两种不同的类型,可变集合set() 和 不可变集合frozenset()。
集合 set 常见函数:
s = set(lambda : value) add(elem) # 向集合中添加数据 update(*others) # 迭代着增加 clear() # 清空集合 discard(elem) # 删除集合中指定的值(不存在则不删除)
集合(set)有两种不同的类型,可变集合set() 和 不可变集合frozenset()。
堆(heap)是一种特殊的数据结构,它是一棵满足堆属性的完全二叉树。堆通常用于实现优先队列等数据结构,在需要高效地找到最大或最小元素时特别有用。
堆 heapq 常见函数:
heap = [] # 建堆 heapq.heappush(heap,item) # 往堆中插入新值 heapq.heappop(heap) # 弹出最小的值 heap[0] # 查看堆中最小的值, 不弹出 heapq.heapify(x) # 以线性时间将一个列表转为堆 heapq.heappoppush(heap, item) # 弹出最小的值.并且将新的值插入其中. heapq.merge(*iterables, key=None, reverse=False) # 将多个堆进行合并 heapq.nlargest(n, iterable, key=None) # 从堆中找出最大的 n 个数,key的作用和sorted( )方法里面的key类似, 用列表元素的某个属性和函数作为关键字 heapq.nsmallest(n, iterable, key=None) # 从堆中找出最小的 n 个数, 与 nlargest 相反
八、函数
def say(message, times = 1): # time 的默认参数值是 1 print message * times return time # 无返回值的函数可省掉 return,等同于return None
只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参。这是因为赋给形参的值是根据位置而赋值的。例如,def func(a, b=5)是有效的,
但是def func(a=5, b)是无效的。
global a # 获得全局变量a
用户自定义函数:
def foo(x,y): print '%s+%s is %s' % (str(x),str(y),str(x+y)) bar=foo bar(3,4) d={} d['callback']=foo d['callback'](3,4) # 调用foo
用户自定义函数有如下属性:
f.__module__ #函数所在的模块名
f.__doc__ 或者 f.func_doc #文档字符串
f.__name__ 或者 f.func_name #函数名
f.__dict__ 或者 f.func_dict #支持任意函数属性的函数名字空间
f.func_code #编译后产生的字节码
f.func_defaults #包含所有默认参数的元组
f.func_globals #函数所在的模块的全局名称空间的字典
f.func_closure #None or a tuple of cells that contain bindings for the function's free variables.
九、类与对象
class Stack(object): def __init__(self): self.stack=[] def push(self,object): self.stack.append(object) def pop(self): return self.stack.pop() def length(self): return len(self.stack) s=Stack() s.push("Dave") s.push(42) s.push([3,4,5]) print s.length() print s.pop() y=s.pop() print y del s
类方法的定义:
# 静态方法: class AClass(object): @staticmethod def astatic(): print 'a static method' # 类方法: class ABase(object): @classmethod def aclassmethod(cls): print 'a class method for',cls.__name__
isinstance(s,C) 用于测试s是否是C或是C的子类的实例
issubclass(A,B) 用于测试A是否是B的子类
所有的 Python 对像都拥有三个特性:身份(可用id()来得到),类型(可用type()来得到),值。
None没有什么有用的属性,它的布尔值总是False。
所有标准对象均可用于布尔测试,同类型的对象之间可以比较大小。每个对象天生具有布尔 True 或 False 值。空对象、值为零的任何数字或者 Null 对象 None 的布尔值都是 False。
创建的类实例如果定义了 nonzero(__nonzero__())或 length(__len__())且值为 0,那么它们的布尔值就是 False。
整数对象和字符串对象是不可变对象,所以 Python 会很高效的缓存它们。这会造成我们认为 Python 应该创建新对象时,它却没有创建新对象的假象。
Python 没有 char 或 byte 类型来保存单一字符或 8 比特整数。你可以使用长度为 1 的字符串表示字符或 8 比特整数。
class Person: def __init__(self, name, age): self.name = name self.age = age def __eq__(self, other): if isinstance(other, Person): return self.name == other.name and self.age == other.age return False # 创建两个Person实例 person1 = Person("Alice", 30) person2 = Person("Alice", 30) person3 = Person("Bob", 30) # 使用==比较 print(person1 == person2) # 输出: True print(person1 == person3) # 输出: False
在Python中,比较两个类的实例是否相等,通常有以下几种方法:
- 使用==运算符:Python中的==运算符默认比较对象的内存地址,即比较两个实例是否为同一个对象。如果你希望比较实例的内容是否相等,需要在类中定义__eq__魔术方法。
- 定义__eq__方法:通过在类定义中实现__eq__方法,可以自定义比较逻辑。这个方法接受一个参数,通常是要比较的另一个对象。如果两个对象相等,返回True,否则返回False。
- 使用is运算符:与==不同,is运算符比较的是两个对象的内存地址,即判断它们是否为同一个实例。
- 使用内置的比较函数:Python的functools模块提供了total_ordering装饰器,可以简化比较方法的实现。如果你实现了__eq__和__lt__(小于)方法,total_ordering会为你生成其他的比较方法。
- 使用hash和eq:如果你希望对象可以作为字典的键或者使用在需要哈希值的集合中,那么除了实现__eq__外,还需要实现__hash__方法。
请注意,如果你定义了__eq__方法,通常也应该定义__ne__(不等于)方法,以确保!=运算符的行为符合预期。如果你使用total_ordering装饰器,并且定义了__eq__和__lt__,那么其他的比较运算符(__le__, __gt__, __ge__)会被自动生成。
十、异常与错误
用try和except语句来捕获异常:
try: f=open("file.txt","r") except IOError,e: print e except TypeError,e: print e ... try: do something except: print 'An error occurred'
如果有IOError异常,就将错误原因放置在对象e中,然后运行except代码块,如果发生其他类型的异常就将控制权转到处理该异常的except的代码块,如果没找到该代码块,程序将终止运行,若没有发生异常,except代
码会被忽略掉。
十一、模块
import 模块名
import 模块名 as 别名
from 模块 import 对象(函数)
from 模块 import *
内建函数dir()可以列出一个模块中的所有可访问的内容
可以被import导入的模块:
1.使用python写的程序(.py程序)
2.C或C++扩展(已编译的共享库或DLL)
3.包(包含多个模块)
4.内建模块(使用C写的并已链接到python解释器内)
一个模块的属性(函数和变量)可以通过熟悉的 .句点属性标识法访问:module.function() module.variable
__name__ 指示模块应如何被加载:如果模块是被导入, __name__ 的值为模块名字。如果模块是被直接执行, __name__ 的值为 '__main__'。
十二、引用与副本
python中的一切数据都是对象。
对于可变对象,改变一个引用就等于改变了该对象的所有的引用:
a=[1,2,3,4] b=a b[2]=100 print a # a=[1,2,100,4]
为了避免这种情况,你需要创建一个可变对象的副本,然后对该副本进行操作。
两种创建可变对象的副本:
(1)浅拷贝(shallow copy):创建一个新对象,但它包含的子元素仍然是原来对象子元素的引用:
b=[1,2,[3,4]] a=b[:] a.append(100) print b # b=[1,2,[3,4]] b没有变 a[0]=100 print b # b=[1,2,[3,4]] b没有变 a[2][0]=100 print b # b=[1,2,[100,4]] b被改变了
(2)深拷贝(deep copy)
import copy b=[1,2,[3,4]] a=copy.deepcopy(b)
__del__()在对象销毁时调用。 del x 只是减少对象x的引用计数,并不调用这个函数。
增加引用计数:对象被创建。或另外的别名被创建。或被作为参数传递给函数(新的本地引用)。或成为容器对象的一个元素。
减少引用计数:一个本地引用离开了其作用范围。对象的别名被显式的销毁(使用del)。 对象被从一个容器对象中移除,如myList.remove(x)。容器对象本身被销毁,如del myList。
十三、类型转换
int(x[,base]) #转换为int
long(x[,base])
float(x)
tuple(x)
list(x)
chr(x) #转换为字符
unichr(x) #转换为Unicode字符
ord(x) #字符转换为整数值
str(x)
a=[1,2,3,4]
s=repr(a) # s='[1,2,3,4]' 也可以使用 s='a'
b=eval(s) # b=[1,2,3,4] 再转换成一个列表
eval('3+4')
f=open("foo")
a=repr(f) # a="<open file 'foo',mode 'r' at dc030>"
十四、其他
文档字符串DocStrings: 如果一个模块、类、函数体的第一个语句是未命名的字符串,改字符串就自动成为该对象的文档字符串 说白了就是类似于JavaDoc的东西。
文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第二行是空行,从第三行开始是详细的描述。可以使用__doc__(注意双下划线)调用函数的文档字符串属性(属于函数的名称)。Python把每一样东西都作为对象,包括这个函数。
Python中的help(),它所做的只是抓取函数的__doc__属性,然后整洁地展示给你。
自动化工具也可以以同样的方式从你的程序中提取文档。随Python发行版附带的pydoc命令,与help()类似地使用DocStrings。
def printMax(x, y): '''Prints the maximum of two numbers.''' # 这里是文档字符串 print "DocStrings" # 这里是函数体命令行参数 >>>print printMax.__doc__ Prints the maximum of two numbers.
id(a)可以查看该对象的标识(当前的实现是该对象在内存中的位置)
if type(a) is type(b): print 'a and b have the same type' if type(a) is types.ListType print 'Is a list'
isinstance(s,C) 用于测试s是否是C或是C的子类的实例
import types isinstance(3,types.IntType) #返回True
x==y 比较x和y的值是否相等
x is y 和x is not y 比较x和y在内存中是否指向同一个对象
推荐文章:
Pyhton简史
http://www.cnblogs.com/vamei/archive/2013/02/06/2892628.html
Python快速教程
http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html
Python入门(一):一句话统计文章不重复汉字数
http://www.cnblogs.com/littlegend/archive/2013/04/12/3016552.html