python
2023-06-20 20:50:34 0 举报
AI智能生成
Python
作者其他创作
大纲/内容
python基础
数据类型
整型
浮点型
字符串
布尔值
字符串和编码
占位符
占位符 替换内容<br>%d 整数<br>%f 浮点数<br>%s 字符串<br>%x 十六进制整数
list和tuple
list
Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
>>> classmates = ['Michael', 'Bob', 'Tracy']<br>>>> classmates<br>['Michael', 'Bob', 'Tracy']
tuple
另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改
因为tuple不可变,所以代码更安全。
条件判断
条件判断
计算机之所以能做很多自动化的任务,因为它可以自己做条件判断。
if添加一个else语句
elif是else if的缩写
if <条件判断1>:<br> <执行1><br>elif <条件判断2>:<br> <执行2><br>elif <条件判断3>:<br> <执行3><br>else:<br> <执行4>
循环
names = ['Michael', 'Bob', 'Tracy']<br>for name in names:<br> print(name)
n = 1
while n <= 100:
print(n)
n = n + 1
print('END')
dict和set
dict
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}<br>>>> d['Michael']
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
函数
调用函数
绝对值的函数abs
max函数
数据类型转换
>>> int('123')<br>123<br>>>> int(12.34)<br>12<br>>>> float('12.34')<br>12.34<br>>>> str(1.23)<br>'1.23'<br>>>> str(100)<br>'100'<br>>>> bool(1)<br>True<br>>>> bool('')<br>False
函数名其实就是指向一个函数对象的引用
>>> a = abs # 变量a指向abs函数<br>>>> a(-1) # 所以也可以通过a调用abs函数<br>1
定义函数
在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
def my_abs(x):<br> if x >= 0:<br> return x<br> else:<br> return -x
子主题
空函数
pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。
if age >= 18:<br> pass
参数检查
允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()实现:<br><br>
def my_abs(x):<br> if not isinstance(x, (int, float)):<br> raise TypeError('bad operand type')<br> if x >= 0:<br> return x<br> else:<br> return -x
返回多个值
import math<br><br>def move(x, y, step, angle=0):<br> nx = x + step * math.cos(angle)<br> ny = y - step * math.sin(angle)<br> return nx, ny
函数参数
默认参数必须指向不变对象!
可变参数
def calc(*numbers):<br> sum = 0<br> for n in numbers:<br> sum = sum + n * n<br> return sum
关键字参数
def person(name, age, **kw):<br> print('name:', name, 'age:', age, 'other:', kw)
命名关键字参数
def person(name, age, **kw):<br> if 'city' in kw:<br> # 有city参数<br> pass<br> if 'job' in kw:<br> # 有job参数<br> pass<br> print('name:', name, 'age:', age, 'other:', kw)
def person(name, age, *, city, job):<br> print(name, age, city, job)
参数组合
def f1(a, b, c=0, *args, **kw):<br> print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)<br><br>def f2(a, b, c=0, *, d, **kw):<br> print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
>>> f1(1, 2)<br>a = 1 b = 2 c = 0 args = () kw = {}<br>>>> f1(1, 2, c=3)<br>a = 1 b = 2 c = 3 args = () kw = {}<br>>>> f1(1, 2, 3, 'a', 'b')<br>a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}<br>>>> f1(1, 2, 3, 'a', 'b', x=99)<br>a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}<br>>>> f2(1, 2, d=99, ext=None)<br>a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
递归函数
高级特性
切片
对这种经常取指定索引范围的操作,用循环十分繁琐,因此,Python提供了切片(Slice)操作符,能大大简化这种操作。
>>> L[0:3]<br>['Michael', 'Sarah', 'Tracy']
迭代
可以看出,Python的for循环抽象程度要高于C的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
列表生成
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
>>> list(range(1, 11))<br>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [x * x for x in range(1, 11)]<br>[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
>>> L = [x * x for x in range(10)]<br>>>> L<br>[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]<br>>>> g = (x * x for x in range(10))<br>>>> g<br><generator object <genexpr> at 0x1022ef630>
迭代器
我们已经知道,可以直接作用于for循环的数据类型有以下几种:<br><br>一类是集合数据类型,如list、tuple、dict、set、str等;<br><br>一类是generator,包括生成器和带yield的generator function。
# 首先获得Iterator对象:<br>it = iter([1, 2, 3, 4, 5])<br># 循环:<br>while True:<br> try:<br> # 获得下一个值:<br> x = next(it)<br> except StopIteration:<br> # 遇到StopIteration就退出循环<br> break
凡是可作用于for循环的对象都是Iterable类型;<br><br>凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;<br><br>集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
函数式编程
高阶函数
map/reduce
Python内建了map()和reduce()函数。
map
>>> def f(x):<br>... return x * x<br>...<br>>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])<br>>>> list(r)<br>[1, 4, 9, 16, 25, 36, 49, 64, 81]
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
reduce
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
>>> from functools import reduce<br>>>> def add(x, y):<br>... return x + y<br>...<br>>>> reduce(add, [1, 3, 5, 7, 9])
filter
Python内建的filter()函数用于过滤序列。
def is_odd(n):<br> return n % 2 == 1<br><br>list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
sorted
Python内置的sorted()函数就可以对list进行排序
>>> sorted([36, 5, -12, 9, -21], key=abs)<br>[5, 9, -12, -21, 36]
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
返回函数
函数作为返回值<br>
def lazy_sum(*args):<br> def sum():<br> ax = 0<br> for n in args:<br> ax = ax + n<br> return ax<br> return sum
>>> f = lazy_sum(1, 3, 5, 7, 9)<br>>>> f<br><function lazy_sum.<locals>.sum at 0x101c6ed90>
闭包<br>
注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。
def count():<br> fs = []<br> for i in range(1, 4):<br> def f():<br> return i*i<br> fs.append(f)<br> return fs<br><br>f1, f2, f3 = count()
>>> f1()<br>9<br>>>> f2()<br>9<br>>>> f3()<br>9
全部都是9!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。
def inc():<br> x = 0<br> def fn():<br> # nonlocal x<br> x = x + 1<br> return x<br> return fn<br><br>f = inc()<br>print(f()) # 1<br>print(f()) # 2
匿名函数
当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。
>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))<br>[1, 4, 9, 16, 25, 36, 49, 64, 81]
装饰器
由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。
>>> def now():<br>... print('2015-3-25')<br>...<br>>>> f = now<br>>>> f()<br>2015-3-25
偏函数
Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。
简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
>>> import functools<br>>>> int2 = functools.partial(int, base=2)<br>>>> int2('1000000')<br>64<br>>>> int2('1010101')<br>85
模块
使用模块
Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。
import sys
导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。
三方模块
在Python中,安装第三方模块,是通过包管理工具pip完成的。
面向对象编程
类和实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
访问限制
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。
class Student(object):<br><br> def __init__(self, name, score):<br> self.__name = name<br> self.__score = score<br><br> def print_score(self):<br> print('%s: %s' % (self.__name, self.__score))
继承和多态
在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
获取对象信息
当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?
实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性。
面向对象高级编程
错误、调式和测试
在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。在操作系统提供的调用中,返回错误码非常常见。比如打开文件的函数open(),成功时返回文件描述符(就是一个整数),出错时返回-1。
try:<br> print('try...')<br> r = 10 / 0<br> print('result:', r)<br>except ZeroDivisionError as e:<br> print('except:', e)<br>finally:<br> print('finally...')<br>print('END')
Python内置的logging模块可以非常容易地记录错误信息
import logging<br><br>def foo(s):<br> return 10 / int(s)<br><br>def bar(s):<br> return foo(s) * 2<br><br>def main():<br> try:<br> bar('0')<br> except Exception as e:<br> logging.exception(e)<br><br>main()<br>print('END')
抛出错误
# err_raise.py<br>class FooError(ValueError):<br> pass<br><br>def foo(s):<br> n = int(s)<br> if n==0:<br> raise FooError('invalid value: %s' % s)<br> return 10 / n<br><br>foo('0')
单元测试
import unittest<br><br>from mydict import Dict<br><br>class TestDict(unittest.TestCase):<br><br> def test_init(self):<br> d = Dict(a=1, b='test')<br> self.assertEqual(d.a, 1)<br> self.assertEqual(d.b, 'test')<br> self.assertTrue(isinstance(d, dict))<br><br> def test_key(self):<br> d = Dict()<br> d['key'] = 'value'<br> self.assertEqual(d.key, 'value')<br><br> def test_attr(self):<br> d = Dict()<br> d.key = 'value'<br> self.assertTrue('key' in d)<br> self.assertEqual(d['key'], 'value')<br><br> def test_keyerror(self):<br> d = Dict()<br> with self.assertRaises(KeyError):<br> value = d['empty']<br><br> def test_attrerror(self):<br> d = Dict()<br> with self.assertRaises(AttributeError):<br> value = d.empty
IO编程
文件读写
读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。
for line in f.readlines():<br> print(line.strip()) # 把末尾的'\n'删掉
StringIO和BytesIO
很多时候,数据读写不一定是文件,也可以在内存中读写。
>>> from io import StringIO<br>>>> f = StringIO()<br>>>> f.write('hello')<br>5<br>>>> f.write(' ')<br>1<br>>>> f.write('world!')<br>6<br>>>> print(f.getvalue())<br>hello world!
>>> from io import StringIO<br>>>> f = StringIO('Hello!\nHi!\nGoodbye!')<br>>>> while True:<br>... s = f.readline()<br>... if s == '':<br>... break<br>... print(s.strip())<br>...<br>Hello!<br>Hi!<br>Goodbye!
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。<br><br>
>>> from io import BytesIO<br>>>> f = BytesIO()<br>>>> f.write('中文'.encode('utf-8'))<br>6<br>>>> print(f.getvalue())<br>b'\xe4\xb8\xad\xe6\x96\x87'
>>> from io import BytesIO<br>>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')<br>>>> f.read()<br>b'\xe4\xb8\xad\xe6\x96\x87'
操作文件
如果我们要操作文件、目录,可以在命令行下面输入操作系统提供的各种命令来完成。比如dir、cp等命令。
>>> import os<br>>>> os.name # 操作系统类型
进程和线程
常用内建模块
第三方模块
0 条评论
下一页