python的基本语法基础讲解
python中,没有:{},也不用每句话才用分号分开。python只通过缩进来分块的,一行占个句话就可以。
语法基础
基本输入输出语句print和raw_input():
#输入语句: >>> print'100+100=%d' %(100+100) 100+100=200 #输出语句 >>> name = raw_input('input your name:') input your name:yinheyi >>> print('hello,%s' %name) hello,yinheyi
注意:raw_input()语句接收以后,默认保存为str格式哦,如果要比较大小的话,记得转为int类型。
>>> number = raw_input('input a number:') input a number:12 >>> type(number) >>> number = int(raw_input('input a number:')) input a number:12 >>> type(number)
判断与循环语句:
判断语句:if…elif…else
>>> if a>= 50: ... print 'the number is big' ... elif a < 50: ... print'the number is small' ... else: ... print "i don't know" ... the number is big
循环语句: for…in
>>> sum = 0 >>> for number in range(101): ... sum = sum + number ... >>> print sum 5050
循环语句: while
>>> sum = 0 >>> n = 1 >>> while n < 101: ... sum = sum + n ... n = n + 1 ... >>> print sum 5050
数据类型:列表、元组、字典、set
list: Python内置的一种数据类型是列表。lists是一个有序的集合,可以添加与删除元素。
生成它是用 [] 就可以啦;
调用它时,用下标调用就可以啦(从0开始);如第一个元素,list[0];倒数第一个,list[-1];
可以用len()函数获得list元素的个数;
在尾部添加用append(), 中间插入用insert();尾部删除用pop();指定位置删除为pop(i);
#定义一个friends的列表 >>> friends = ['xiaoming','ergou','sanmao'] >>> friends ['xiaoming', 'ergou', 'sanmao'] >>> friends[0] 'xiaoming' >>> friends[-1] 'sanmao' #添加与删除 >>> friends.append('dapeng') >>> friends ['xiaoming', 'ergou', 'sanmao', 'dapeng'] >>> friends.insert(0,'diyi') >>> friends ['diyi', 'xiaoming', 'ergou', 'sanmao', 'dapeng'] >>> friends.pop() 'dapeng' >>> friends ['diyi', 'xiaoming', 'ergou', 'sanmao'] >>> friends.pop(2) 'ergou' >>> friends ['diyi', 'xiaoming', 'sanmao'] #替换 >>> friends[0] = 'wangbadan' >>> friends ['wangbadan', 'xiaoming', 'sanmao']
元组(tuple):tuple和list非常类似,但是tuple一旦初始化就不能修改。只要记住它不能修改就可以啦。很安全。
用 () 定义啊。
用下标调用,即tuple[1];
注意:它定义一个元素的tuple时,一定要这样写,如:name = (‘yin’,), 千万别写成 name = (‘yin’);
name = ('zhai','yin') >>> name ('zhai', 'yin') >>> name[0] 'zhai' >>> name[-1] 'yin'
字典(dictionary):它就是键-值对。如在C++语言中为map的容器。它的特点就是可以快速查找,需要占用大量的内存,内存浪费多。通过key计算位置的算法称为哈希算法(Hash)。
用 {} 定义dictionary哦;
随着dictionary的增加,查找时间不会增加的。
多次对一个key放入value,后面的值会把前面的值冲掉:
可以用 ‘key’in dic 或 dic.get(‘key’)的方法来查看key是否存在。注意:dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value,返回None的时候Python的交互式命令行不显示结果。
删除用: pop(key)。添加时,直接用key值的索引添加就可以的。
注意:ict内部存放的顺序和key放入的顺序是没有关系的。
#定义一个dictionary; score = {'xiaoming':85,'xiaohong':62} >>> score {'xiaoming': 85, 'xiaohong': 62} #添加一个元素; >>> score['wangdan'] = 85 >>> score {'xiaoming': 85, 'xiaohong': 62, 'wangdan': 85} #删除一个元素; >>> score.pop('xiaohong') 62 >>> score {'xiaoming': 85, 'wangdan': 85} #查看key是否存在; >>> 'xiaoming' in score True #查看一个key对应的值; >>> score.get('wangdan') 不存在时,返回一个自定义的值; 85>>> score.get('hehehe',-1) -1
set:set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象。
要创建一个set,需要提供一个list作为输入集合:
通过add(key)与remove(key)添加与删除元素;
>>> s = set([1, 2, 3]) >>> s set([1, 2, 3])
注意,传入的参数[1, 2, 3]是一个list,而显示的set([1, 2, 3])只是告诉你这个set内部有1,2,3这3个元素,显示的[]不表示这是一个list。
重复元素在set中自动被过滤:
>>> s = set([1, 1, 2, 2, 3, 3]) >>> s set([1, 2, 3])
添加与删除
>>> s = set([1,2,3]) >>> s set([1, 2, 3]) >>> s.add('xiaoming') >>> s set([1, 2, 3, 'xiaoming']) >>> s.add(0) >>> s set([0, 1, 2, 3, 'xiaoming']) >>> s.remove(2) >>> s set([0, 1, 3, 'xiaoming'])
一些高级操作:
对于list与tuple的切片操作:
如list[:5]或list[0:5]表示第0,1,2,3,4个索引值;当然也可以为负的如,list[-2:0]等于list[-2:]即倒数第2、倒数第1个数;也可以跳着来哦:list[1:10:2],表示步长为2的。
list=range(100) #正着切片 >>> list[:10] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #负索引切片 list[-10:] [90, 91, 92, 93, 94, 95, 96, 97, 98, 99] #倒着切片 >>> list[10:0:-1] [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] >>> list[-1:-10:-1] [99, 98, 97, 96, 95, 94, 93, 92, 91] #跳着切片 >>> list[::10] [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
#tuple的切片 >>> (0, 1, 2, 3, 4, 5)[:3] (0, 1, 2) #字符串的切片 >>> 'ABCDEFG'[:3] 'ABC' >>> 'ABCDEFG'[::2] 'ACEG'
它的迭代:
对于list、tuple还有字符串都可以用 for…in 进行迭代哦;
而对于dictionary的话,也可以哦,只不过默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.itervalues(),如果要同时迭代key和value,可以用for k, v in d.iteritems()。
那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
另外:Python内置的enumerate函数可以把一个list、tuple、字符串本身变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
>>> from collections import Iterable >>> isinstance('abc', Iterable) # str是否可迭代 True >>> isinstance([1,2,3], Iterable) # list是否可迭代 True >>> isinstance(123, Iterable) # 整数是否可迭代 False
列表生成式:很牛逼很方便的;它是用来创建list的生成式;我们举例子看看哈:
生成1-10的list:
>>> range(1,11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
生成 12、22、……102的list:
>>> list = [x*x for x in range(1,11)] >>> list [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
还可以再选择一下哦:
>>> [x * x for x in range(1, 11)if x % 2 == 0] [4, 16, 36, 64, 100]
还可以两层循环的:
>>> [m + n for m in 'ABC' for n in 'XYZ'] ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
生成器:
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
创建方法1:第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
>>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> g at 0x104feab40>
可以通过generator的.next()方法打印出来数据,另外也可以通过迭代哦,基本上我们都选择for…in迭代方法。
创建方法2:通过特殊函数创建:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。
#这是函数,输出斐波那契数列 def fib(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1 #这是generator,也是生成斐波那契数列; def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1
注意:这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
>>> def odd(): ... print 'step 1' ... yield 1 ... print 'step 2' ... yield 3 ... print 'step 3' ... yield 5 ... >>> o = odd() >>> o.next() step 1 1 >>> o.next() step 2 3 >>> o.next() step 3 5 >>> o.next() Traceback (most recent call last): File "", line 1, in StopIteration
函数式编程
高阶函数
函数可以赋值给变量,可以当成参数传递给函数map:对每个列表中得元素作用一个函数,并返回。reduce:将结果和下个元素传给函数,最终返回一个结果。filter:过滤器,使用方法跟map差不多,是返回结果为true的元素sorted:排序,跟map差不多
返回函数
可以在函数中定义函数,并返回。就像一个变量一样。闭包:返回的函数可以使用定义函数内部的变量
匿名函数
匿名函数即lamdba表达式:lamdba 参数 : 表达式
装饰器
概念:即在函数执行前后加一些逻辑不想管的代码,比如log实现
def log(func): @functools.wraps(func) def wrapper(*args, **kw): print 'call %s():' % func.__name__ return func(*args, **kw) return wrapper
@log def now(): print '2013-12-25'
偏函数
简单的讲就是创建具有特定模式的函数别名,这个特定模式大概指的是设定好某些参数(默认参数),来达到简写的目的。
int2 = functools.partial(int, base=2)这样就创建了一个专门转化二进制的函数了。因为我们设定了默认参数 base = 2当参数太多需要简化的时候就是用偏函数
模块
模块
一个py文件就是一个模块,目录就是包名
使用模块
这是一个标准的模块模板
#!/usr/bin/env python # -*- coding: utf-8 -*- ' a test module ' __author__ = 'Michael Liao' import sys def test(): args = sys.argv if len(args)==1: print 'Hello, world!' elif len(args)==2: print 'Hello, %s!' % args[1] else: print 'Too many arguments!' if __name__=='__main__': test()
模块内部的私有变量和函数一律使用_开头,且不要在外部进行引用。
安装第三方模块
pip install 模块名称
使用__future__
future可以把下个版本的新功能添加到当前版本
面向对象编程
类和实例
定义类
class ClassName(SuperClass): pass
构造方法def __init__(self,args)`
访问限制
使用__双下划线开头可以让变量成为私有,外部无法访问。也可以通过添加getter、setter来控制访问操作。
继承和多态
继承就在定义的时候写上父类的名称,多态就覆盖父类的方法。
获取对象信息
使用type()判断类型信息使用isinstance()判断继承关系使用dir()获取对象的所有方法和属性
面向对象高级编程
使用slots
动态添加属性:instance.pro = 10动态添加方法:instance.newmethod = MethodType(method_name, instance, class_name)为了防止胡乱添加属性可以使用__slots__ = (被允许的属性)
使用@property
如下,定义了一个score的属性
@property def score(self): return self._score @score.setter def score(self, value): if not isinstance(value, int): raise ValueError('score must be an integer!') if value < 0 or value > 100: raise ValueError('score must between 0 ~ 100!') self._score = value
多重继承
最好不要用多重继承,用mixinmixin其中概念,用类来提供一组相似功能。类似实现过的接口。
定制类
使用类似slots 来定制一个类的行为。str 打印类时的信息repr直接写打印出来的信息iter 用于 for ... in迭代,__iter__返回下一个迭代对象,next()用于拿到循环的下一个值getitem 提供下标访问getattr 当找不到这个属性的时候会调用这个方法call 当使用instance()这样来把对象实例当成方法调用的时候,其实调用的就是__call__。可以使用callable(thing)来判断一个东西是否可以被当成方法调用
使用元类
types():使用它来动态构建类,方法是types('ClassName', (SuperClass, ), dict(methodName = method))
错误、调试和测试
错误
try...except...finally...错误基类是BaseException常见的错误类型记录错误,使用python模块logginglogging.exception(exception instance)可以将错误调用对战输出出来也可以自定义错误类型,方法是继承自某个Exception,然后使用raise语句直接写raise可以把当前exception抛出,让上层调用处理。
调试
断言:assert is true , 'error message'logging可以方便的输出日志,包括错误。logging.info('info')。method可以是debug,info,warning,error中的一个。可以指定当前输出的method,方法是指定当前输出级别logging.basicConfig(level=logging.INFO)pdb:python -m pdb err.py 开始调试 l 查看代码 n单步执行 p查看变量 q结束测试 c继续执行程序内部设置断点:import pdb,在可能出错的地方放置pdb.set_trace()