python第一部分学习
一、python基础
1、数据类型和变量
- 内存机制:自动回收
- 常用数据类型:int 、float、str、list、typle(元组)、set(集合)、dict(字典)、空值
- 命名习惯
- 转义字符
- 调试工具
2、字符串和编码
- Unicode,utf8,
- str ,bytes
- # -*- coding: utf-8 -*-
- 进制转换
- 对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符
- ecode()和decode(),len()
- %运算符用来格式化字符串的及相关格式化
%d 整数 %f 浮点数 %s 字符串 %x 十六进制整数
3、使用list和tuple
(1)、list
- Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
- 用len()函数可以获得list元素的个数:
- 当索引超出了范围时,Python会报一个IndexError错误,所以,要确保索引不要越界,记得最后一个元素的索引是len(classmates) - 1
- list是一个可变的有序表,所以,可以往list中追加元素到末尾:append()方法
- 也可以把元素插入到指定的位置,比如索引号为1的位置:insert()方法
- 要删除list末尾的元素,用pop()方法:
- 要删除指定位置的元素,用pop(i)方法,其中i是索引位置:
- 要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:
- list元素也可以是另一个list s = ['python', 'java', ['asp', 'php'], 'scheme']
- 如果一个list中一个元素也没有,就是一个空的list,它的长度为0:
(2)、tuple
- 另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的
- 如果要定义一个空的tuple,可以写成()
- 要定义一个只有1个元素的tuple ,加逗号消除歧义 t = (1,)
- “可变的”tuple:变的不是tuple的元素,而是list的元素
4、条件判断
- 条件循环缩进控制代码块
- if....elif......else 注意不要少写了冒号:
- input 和print
5、循环
- 第一种循环是for...in循环,依次把list或tuple中的每个元素迭代出来,注意不要少写了冒号:
- 第二种循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环
- range()函数
- break和continue
6、dict和set
(1)dict
- Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度 d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
- 由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:
- 如果key不存在,dict就会报错:
- 要避免key不存在的错误,有两种办法,
一是通过in判断key是否存在: 'Thomas' in d
二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:
- 要删除一个key,用pop(key)方法,对应的value也会从dict中删除:
- 和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
占用空间小,浪费内存很少。
(2)set
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;占用空间小,浪费内存很少。
(2)set
- set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
- 要创建一个set,需要提供一个list作为输入集合: s = set([1, 2, 3])
- 重复元素在set中自动被过滤:
- 通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:
- 通过remove(key)方法可以删除元素:
- set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
- 不可变对象:转换之后本身是不可变得,变化的是转换之后的变量
- 字符串replace()方法
二、函数
1、调用函数
- Python内置的常用函数还包括数据类型转换函数,比如int()函数可以把其他数据类型转换为整数
- 函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
2、定义函数
- 在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
- 如果想定义一个什么事也不做的空函数,可以用pass语句:
- import
- 参数检查:调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError,但是如果参数类型不对,Python解释器就无法帮我们检查
- 数据类型检查可以用内置函数isinstance()实现:
- 返回多个值
3、函数的参数
这里是重点
- 位置参数
- 默认参数 ,使用默认参数要注意两点:
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数。
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
使用默认参数有什么好处?最大的好处是能降低调用函数的难度。
- 可变参数 ,定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号,def calc(*numbers)
Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:*nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相 当有用,而且很常 见。
- 关键字参数
- 命名关键字参数
- 参数组合
4、递归函数
- 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
- 汉诺塔
三、高级特性
1、切片
- L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
- 如果第一个索引是0,还可以省略: L[:3]
- 也可以从索引1开始,取出2个元素出来:L[1:3]
- 既然Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片,记住倒数第一个元素的索引是-1。 L[-2:] L[-2:-1]
- 可以通过切片轻松取出某一段数列。
比如前10个数:L[:10] ,
后10个数:L[-10:],
前11-20个数:L[10:20],
前10个数,每两个取一个:L[:10:2],
所有数,每5个取一个:L[::5]
甚至什么都不写,只写[:]就可以原样复制一个list:L[:]
- tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
- 字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
2、迭代
- 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。
- 在Python中,迭代是通过for ... in来完成的,而很多语言比如C语言,迭代list是通过下标完成的
- 因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。
- 默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。
- 如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断: isinstance('abc', Iterable) # str是否可迭代
- 如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:for i, value in enumerate(['A', 'B', 'C']):
- for循环里,同时引用了两个变量,在Python里是很常见的 for x, y in [(1, 1), (2, 4), (3, 9)]:
3、列表生成式
- 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
- 写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来 [x * x for x in range(1, 11) if x % 2 == 0]
- 还可以使用两层循环,可以生成全排列 [m + n for m in 'ABC' for n in 'XYZ']
- for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value: for k, v in d.items():
- 列表生成式也可以使用两个变量来生成list: [k + '=' + v for k, v in d.items()]
- 使用列表生成式的时候,if...else的用法。
在一个列表生成式中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else
[x for x in range(1, 11) if x % 2 == 0] [x if x % 2 == 0 else -x for x in range(1, 11)]
- str有lower()方法,大写转小写
4、生成器
- 如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
- 第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator: g = (x * x for x in range(10))
- 可以通过next()函数获得generator的下一个返回值:,正确的方法是使用for循环,因为generator也是可迭代对象:
- 斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
- yield。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
- 杨辉三角
5、迭代器
我们已经知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象: isinstance([], Iterable)
四、函数式编程
1、高阶函数
- 变量可以指向函数
- 函数名也是变量
- 变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。add(-5, 6, abs)
- map/reduce:
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。 r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就 是: reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
- filter:
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素
注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。
- sorted:
Python内置的sorted()函数就可以对list进行排序
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序 sorted([36, 5, -12, 9, -21], key=abs)
2、返回函数
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
3、匿名函数
当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。 list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
关键字lambda表示匿名函数,冒号前面的x表示函数参数
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
4、装饰器
- 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。
- 函数对象有一个__name__属性,可以拿到函数的名字: f.__name__
- 假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数
- Python的@语法
- import functools
5、偏函数’
int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换: int('12345', base=8)
五、模块
六、面向对象编程
1、类和实例
2、访问限制
3、继承和多态
4、获取对象信息
5、实例属性和类属性
七、面向对象高级编程
1、使用__slots__
2、使用@propertry
3、多重继承
4、定制类
5、使用枚举类
6、使用元类
人生若只如初见,何事秋风悲画扇?
等闲变却故人心,却道故人心易变。
骊山语罢清宵半,泪雨零铃终不怨。
何如薄倖锦衣郎,比翼连枝当日愿!
#39Hello##Python#等闲变却故人心,却道故人心易变。
骊山语罢清宵半,泪雨零铃终不怨。
何如薄倖锦衣郎,比翼连枝当日愿!