python3 基础学习笔记
2018-03-23 10:19
288 查看
记录学习廖雪峰的python教程,摘要重点
1、基础
1.1数据类型和变量
l 字符串:转义字符
\可以转义很多字符,比如
\n表示换行,
\t表示制表符,字符
\本身也要转义,所以
\\表示的字符就是
\;
为了简化,Python还允许用
r''表示
''内部的字符串默认不转义
如果字符串内部有很多换行,用
\n写在一行里不好阅读,为了简化,Python允许用
'''...'''的格式表示多行内容
l 空值
空值是Python里一个特殊的值,用
None表示。
None不能理解为
0,因为
0是有意义的,而
None是一个特殊的空值。
l 变量
在Python中,等号
=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量
理解变量在计算机内存中的表示也非常重要,如写 a = 'ABC'时,Python解释器干了两件事情: 1、在内存中创建了一个'ABC'的字符串;2、在内存中创建了一个名为a的变量,并把它指向'ABC'。
a = 'ABC'
b = a
a = 'XYZ'
print(b) b的值是’ABC’
l 常量所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量
l 小结
Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。
对变量赋值x = y是把变量x指向真正的对象,该对象是变量y所指向的。随后对变量y的赋值不影响变量x的指向。
注意:Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647。
Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。
1.2、字符串和编码
l Python字符串在最新的Python 3版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言。
print('包含中文的str')
对于单个字符的编码,Python提供了
ord()函数获取字符的整数表示,
chr()函数把编码转换为对应的字符由于Python的字符串类型是
str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把
str变为以字节为单位的
bytes。Python对
bytes类型的数据用带
b前缀的单引号或双引号表示
要注意区分
'ABC'和
b'ABC',前者是
str,后者虽然内容显示得和前者一样,但
bytes的每个字符都只占用一个字节
以Unicode表示的
str通过
encode()方法可以编码为指定的
bytes,例如
反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是
bytes。要把
bytes变为
str,就需要用
decode()方法
l 格式化
%运算符就是用来格式化字符串的。
l 小结Python 3的字符串使用Unicode,直接支持多语言。当
str和
bytes互相转换时,需要指定编码。最常用的编码是
UTF-8。Python当然也支持其他编码方式,比如把Unicode编码成
GB2312:
>>> '中文'.encode('gb2312')
b'\xd6\xd0\xce\xc4'但这种方式纯属自找麻烦,如果没有特殊业务要求,请牢记仅使用
UTF-8编码。
1.3、list 和 tuple
l List:(可以使用list来模拟堆栈和队列)Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
追加元素: List.append(‘xxx’)
插入元素:list.insert(1,’xxxx’)
删除元素:list.pop(i)删除索引为i的元素。
替换元素: list(i)=’xxxx’
l Tuple:元组
tuple和list非常类似,但是tuple一旦初始化就不能修改,因为tuple不可变,所以代码更安全
看一个“可变的”tuple:t = ('a','b',['A','B']) t[2][0]=’X’ t变为('a','b',['X','B'])
变得是list的元素,tuple指向的list没有变
l 小结
list和tuple是Python内置的有序集合,一个可变,一个不可变。根据需要来选择使用它们。
1.4、dict和set
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样,取的时候才能根据key直接拿到value。
一个key只能对应一个value,如果key不存在,dict就会报错;
要避免key不存在的错误,有两种办法,一是通过
in判断key是否存在,(注意:返回
None的时候Python的交互环境不显示结果。)
二是通过dict提供的
get()方法,如果key不存在,可以返回
None,或者自己指定的value:
要删除一个key,用
pop(key)方法,对应的value也会从dict中删除:
dict是用空间来换取时间的一种方法。
dict的key必须是不可变对象。要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key
l set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。要创建一个set,需要提供一个list作为输入集合set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作l 不可变对象
所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
函数
2.1 函数调用
l 小结定义函数时,需要确定函数名和参数个数;如果有必要,可以先对参数的数据类型做检查;函数体内部可以用return随时返回函数结果;函数执行完毕也没有
return语句时,自动
return None。函数可以同时返回多个值,但其实就是一个tuple。
2.2函数的参数
Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数(位置参数)外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。l 默认参数
定义默认参数要牢记一点:默认参数必须指向不变对象!l 可变参数
可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个
*号。在函数内部,参数
numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
所以Python允许你在list或tuple前面加一个
*号,把list或tuple的元素变成可变参数传进去。
def calc(*numbers):xxxxx
>>>nums = [1,2,3]
>>>calc(*nums)
l 关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。def person(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
>>>extra = {'city': 'Beijing','job': 'Engineer'}
>>>person('Jack',24,**extra)
name: Jack age:24 other: {'city': 'Beijing','job': 'Engineer'}
**extra表示把
extra这个dict的所有key-value用关键字参数传入到函数的
**kw参数,
kw将获得一个dict,注意
kw获得的dict是
extra的一份拷贝,对
kw的改动不会影响到函数外的
extra。
l 命名关键字参数
def person(name,age,*,city,job):print(name,age,city,job)
和关键字参数
**kw不同,命名关键字参数需要一个特殊分隔符
*,
*后面的参数被视为命名关键字参数。
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符
*了:
defperson(name,age,*args,city,job):
print(name,age,args,city,job)
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
l 参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!要注意定义可变参数和关键字参数的语法:*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。以及调用函数时如何传入可变参数和关键字参数的语法:可变参数既可以直接传入:
func(1,2,3),又可以先组装list或tuple,再通过
*args传入:
func(*(1,2,3));关键字参数既可以直接传入:
func(a=1,b=2),又可以先组装dict,再通过
**kw传入:
func(**{'a': 1,'b': 2})。使用
*args和
**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符
*,否则定义的将是位置参数。
3 高级特性
3.1切片
L = list(range(100))请写出:L[:10] L[2:10] L[:10:2] L[:] L[: : 5]
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
>>> (0,1,2,3,4,5)[:3]
(0,1,2)
字符串
'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
>>> 'ABCDEFG'[::2]
'ACEG'
3.2 迭代
如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。List,tuple,dict对象均可迭代。
默认情况下,dict迭代的是key。如果要迭代value,可以用
for value in d.values(),如果要同时迭代key和value,可以用
for k,v in d.items()。
如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
from[code] collectionsimport
Iterable
isinstance('abc'
,Iterable)# str是否可迭代[/code]如果要对list实现类似Java那样的下标循环怎么办?Python内置的(枚举)
enumerate函数可以把一个list变成索引-元素对,这样就可以在
for循环中同时迭代索引和元素本身:
for[code] i,valuein
enumerate(['A'
,'B'
,'C'
]):
... [code] print(i,value)
3.3 列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。如:list(range(1,11))For循环前,写元素表达式,For循环后,还可以加上if判断
>>> [code][x * xfor
xin
range(1
,11
)if
x%2
==0
]
[4
,16
,36
,64
,100
]还可以使用两层循环,可以生成全排列:
>>> [code][m + nfor
min'ABC'for
nin'XYZ'
]
['AX'
,'AY'
,'AZ'
,'BX'
,'BY'
,'BZ'
,'CX'
,'CY'
,'CZ'
]import os # 导入os模块,模块的概念后面讲到
>>>[d for d in os.listdir('.')] # os.listdir可以列出文件和目录
for循环其实可以同时使用两个甚至多个变量,比如
dict的
items()可以同时迭代key和value
>>>d = {'x': 'A','y': 'B','z': 'C' }
>>>[k + '=' + v for k,v in d.items()]
['y=B','x=A','z=C']
最后把一个list中所有的字符串变成小写:
>>>L = ['Hello','World','IBM','Apple']
>>>[s.lower()for s in L] #小写 ///// [s.upper()for s in L] #大写
['hello','world','ibm','apple']
使用内建的
isinstance函数可以判断一个变量是不是字符串:isinstance(x,str)
3.4 生成器
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。只要把一个列表生成式的
[]改成
(),就创建了一个generator
g = (x *xforx inrange(10))
>>>g
<generatorobject <genexpr> at 0x1022ef630>
可以通过
next()函数获得generator的下一个返回值。一次次调用next()太变态,正确的方法是使用
for循环,因为generator也是可迭代对象
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的
for循环无法实现的时候,还可以用函数来实现。如斐波那契数列。
要把
fib函数变成generator,只需要把
print(b)改为
yield b就可以了:
这就是定义generator的另一种方法。如果一个函数定义中包含
yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到
return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用
next()的时候执行,遇到
yield语句返回,再次执行时从上次返回的
yield语句处继续执行。
3.5 迭代器
凡是可作用于for循环的对象都是
Iterable类型;可以被
next()函数调用并不断返回下一个值的对象称为迭代器:
Iterator。它们表示一个惰性计算的序列;生成器都是
Iterator对象,集合数据类型如
list、
dict、
str等是
Iterable但不是
Iterator,不过可以通过
iter()函数获得一个
Iterator对象。Python的
for循环本质上就是通过不断调用
next()函数实现的,例如
4、函数式编程
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。高阶函数
l 函数本身也可以赋值给变量,即:变量可以指向函数。l 那么函数名是什么呢?函数名其实就是指向函数的变量!
l 传入函数:既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
小结把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
Map/reduce
所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:>>> list(map(str,[1,2,3,4,5,6,7,8,9]))
['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)
如把序列
[1,3,5,7,9]变换成整数
13579
>>> from functools import reduce
>>> def fn(x,y):
... returnx * 10 + y
...
>>> reduce(fn,[1,3,5,7,9])
13579
filter
Python内建的filter()函数用于过滤序列。和
map()类似,
filter()也接收一个函数和一个序列。和
map()不同的是,
filter()把传入的函数依次作用于每个元素,然后根据返回值是
True还是
False决定保留还是丢弃该元素。注意到
filter()函数返回的是一个
Iterator,也就是一个惰性序列,所以要强迫
filter()完成计算结果,需要用
list()函数获得所有结果并返回list。
Sorted 排序函数
Python内置的sorted()函数就可以对list进行排序:此外,
sorted()函数也是一个高阶函数,它还可以接收一个
key函数来实现自定义的排序,例如按绝对值大小排序:
要进行反向排序,不必改动key函数,可以传入第三个参数
reverse=True:
返回函数
当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数
def lazy_sum(*args):
defsum():
ax = 0
forn in args:
ax = ax + n
returnax
returnsum
当我们调用
lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:
闭包
注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了
f()才执行。返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
匿名函数
关键字lambda表示匿名函数,冒号前面的
x表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写
return,返回值就是该表达式的结果。用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
#将匿名函数作为返回值
def build(x,y):
return lambda: x*x+y*y
q=build(5,8)()
print(q)
输出为89.
装饰器
假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改
now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:
import[code] functools
deflog(func):
@functools.wraps(func)[/code]
defwrapper(*args,**kw):[/code]
print('call %s():'
% func.__name__)
return
func(*args,**kw)
return
wrapper
@log
def now():
print('2015-3-25')
只需记住在定义
wrapper()的前面加上
@functools.wraps(func)即可。
偏函数
int()函数可以把字符串转换为整数,当仅传入字符串时,
int()函数默认按十进制转换:还提供额外的
base参数,默认值为
10。如果传入
base参数,就可以做N进制的转换:
>>> int('12345',base=8)
5349
>>> int('12345',16)
74565
假设要转换大量的二进制字符串,每次都传入
int(x,base=2)非常麻烦,于是,我们想到,可以定义一个
int2()的函数,默认把
base=2传进去
defint2(x,base=2):
return
int(x,base)
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义
int2(),可以直接使用下面的代码创建一个新的函数
int2:
>>> import functools
>>> int2 = functools.partial(int,base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
简单总结
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
创建偏函数时,实际上可以接收函数对象、
*args和
**kw这3个参数
当函数的参数个数太多,需要简化时,使用
functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
模块
文件www.py的模块名就是
mycompany.web.www,两个文件
utils.py的模块名分别是
mycompany.utils和
mycompany.web.utils。
自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。
使用内置模块
使用sys模块的第一步,就是导入该模块: 导入
sys模块后,我们就有了变量
sys指向该模块,利用
sys这个变量,就可以访问
sys模块的所有功能。
sys模块有一个
argv变量,用list存储了命令行的所有参数。
argv至少有一个元素,因为第一个参数永远是该.py文件的名称,例如:运行
python3 hello.py获得的
sys.argv就是
['hello.py'];运行
python3 hello.py Michael获得的
sys.argv就是
['hello.py','Michael]。
if __name__=='__main__':
test()
__name__ 是当前模块名,当模块被直接运行时模块名为 __main__ 。这句话的意思就是,当模块被直接运行时,以下代码块将被运行,当模块是被导入时,代码块不被运行。l 作用域在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过
_前缀来实现的。类似
_xxx和
__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如
_abc,
__abc等;
6、面向对象编程
所以,面向对象的设计思想是抽象出Class,根据Class创建Instance。面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。数据封装、继承和多态是面向对象的三大特点,我们后面会详细讲解。
类和实例
class Student(object):pass
class后面紧接着是类名,即
Student,类名通常是大写开头的单词,紧接着是
(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用
object类,这是所有类最终都会继承的类。
bart =Student() 创建实例是通过类名+()实现的
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的
__init__方法,在创建实例的时候,就把
name,
score等属性绑上去:
注意到
__init__方法的第一个参数永远是
self,表示创建的实例本身,因此,在
__init__方法内部,就可以把各种属性绑定到
self,因为
self就指向创建的实例本身。
数据封装
面向对象编程的一个重要特点就是数据封装。在上面的Student类中,每个实例就拥有各自的
name和
score这些数据。我们可以通过函数来访问这些数据,比如打印一个学生的成绩:>>>bart.print_score()BartSimpson: 59方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。print(lisa.name,lisa.get_grade())
print(bart.name,bart.get_grade())
和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
6.2 访问限制
但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、
score属性:
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线
__,在Python中,实例的变量名如果以
__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
双下划线结尾变量:变量名类似
__xxx__的是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用
__name__、
__score__这样的变量名
单下划线变量:比如
_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问
__name是因为Python解释器对外把
__name变量改成了
_Student__name,所以,仍然可以通过
_Student__name来访问
__name变量
6.3 继承和多态(重难点)
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431865288798deef438d865e4c2985acff7e9fad15e3000由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保
run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:对扩展开放:允许新增
Animal子类;对修改封闭:不需要修改依赖
Animal类型的
run_twice()等函数。
静态语言 vs 动态语言
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是
Animal类型或者它的子类,否则,将无法调用
run()方法。对于Python这样的动态语言来说,则不一定需要传入
Animal类型。我们只需要保证传入的对象有一个
run()方法就可以了:这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
小结
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。6.4 获取对象信息
当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?l 使用type()l 使用isinstance() 总是优先使用isinstance()判断类型,可以将指定类型及其子类“一网打尽”。l 使用dir():获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,类似
__xxx__的属性和方法在Python中都是有特殊用途的,比如
__len__方法返回长度。剩下的都是普通属性或方法,
小结
通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。要注意的是,只有在不知道对象信息的时候,我们才会去获取对象信息。6.5 实例属性和类属性
在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性相关文章推荐
- 【零基础入门学习Python笔记004】改进第一次设计的游戏
- python基础教程_学习笔记18:标准库:一些最爱——shelve
- Python 基础学习笔记1
- 【零基础入门学习Python笔记009】了不起的分支和循环3
- python基础教程_学习笔记11:魔法方法、属性和迭代器
- <<Python基础教程>>学习笔记 | 第13章 | 数据库支持
- Python-基础学习笔记(六)
- Python 基础学习笔记
- Python3学习笔记【基础3--list,tuple,if条件判断,for/while循环,dict字典,set集合】
- python学习笔记之基础数据和控制
- Python基础教程 第11章: 文件和流 学习笔记
- Python学习笔记---基础知识
- 【Python学习笔记】基础
- 个人学习Python笔记-基础技能
- python学习笔记.字典基础操作
- python基础教程_学习笔记3:列表
- python基础教程学习笔记 —字符串
- Python基础语法学习笔记
- Python 学习笔记(一) python基础
- python基础学习笔记分享版(1)