PYTHON笔记本

PYTHON

Basic

2017.10.24

安装: Mac 版本10.12.6

安装homebrew终端运行

1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装python3

1
brew install python3

安装完成之后,在终端运行python3 就进入交互模式,在>>>之后输入代码,回车之后就直接运行。exit()退出交互模式。

或使用文本编辑器sublime等。编辑代码,开头加入#!/usr/bin/env python3并保存为.py后缀的文件。在终端内直接输入文件路径即可执行结果。

mac终端bash 文件运行提示:Permission denied,处理方法:先bash到文件所在位置,运行命令chmod a+x ./filename

基础:输出print() 可以接受多个字符串,逗号会输出成空格;算式可以输出计算结果;输入input();输出一些特殊符号时使用\转义符号,\n表示换行,例如:

1
2
3
>>> print('\\\n\\')
\
\

还可以用r''表示’ ‘内部的默认不转义,例如:

1
2
>>> print(r'\\\n\\')
\\\n\\

数据类型:整数、浮点、字符串、布尔值(true/false,可以用and、or、not计算)、空值(none,不是0)、变量、常量、列表、元组

复数 z=a+bj j代表虚数部分,a b皆为浮点型 z.real实数部分。z.imag 虚数部分。

数字类型间转换:int()float()complex()复。注意复数不能直接转化为整和浮点,不过它们可以混合运算,结果为最宽类型(int<float<complex)

type()返回类型

字符串方法:

1
2
3
4
5
6
7
8
<string>.upper() #小写
.lower() #大写
.capitalize() #首字母大写
.strip() #去除两边空格or指定符
.isdigit() #是否数字类型 True/False
.find() #搜索指定串 返回起始索引
.replace() #参数1被替换的,参数2用了替换的
len(string) #返回长度

除法:/(结果为浮点型) 地板除://(取整)取余%

字符编码:从ASCII到统一标准的Unicode,以及对Unicode作出简化的UTF-8。python3使用Unicode编码,意味着适用于所有语言,ord() 将字符串显示为其十进制的Unicode编码,chr()将编码显示为字符串。

在代码前面写# -*- coding: utf-8 -*-以保证使用UTF-8编码

格式化字符串运算符%

1
2
>>> print('this is %s, %d years old'%('Mike',20))
this is Mike, 20 years old
%d 整数占位符
%s 字符串
%f 浮点数
%x 十六位进制数

Format格式化字符串:eg

1
2
3
print("他是{},今年{}岁"format("Tom",21))
>>>
他是Tom,今年21

列表list有序集合,和js数组一样,用[ ]定义,用[]获取。len()获取长度。[-1]索引为-1获取倒数第一个元素

<seq>+<seq>连接

<sep>*<整数> 整数次重复

<expr> in <seq> 成员检查

.append()插入新元素到列表末尾

.pop(i)删除索引为i的元素,无参数时删除末尾元素,并获取被删除元素。

.insert(i,x)插入元素x到位置i

.index(x)x的索引

元组tuple:用()定义,逗号分隔,定义时就需确定其元素组成,元组之所以为元组在于其不可变性,没有类似list这样的append方法,不过也是用[]获取。元组中各个元素随便什么类型。+ * 进行运算

条件判断if python特别的就是不打括号,但要注意冒号和两格缩进,以及else if 缩写成elif

1
2
3
4
5
6
7
age=int(input())
if age<6:
print('child')
elif age<18:
print('teenager')
else:
print('adult')

(age想用input输入但是报错?因为input返回的数据类型是str,用int()来将字符串类型转化为整数类型)

循环之for in 迭代list或tuple中的每一个元素,计数循环。例如:

1
2
3
nums=[1,2,23,4,5,67,7]
for n in nums:
print(n)

如何计算1-100的整数之和?tips:range(101) 可以生成1到100的整数序列,list()可以将他转位list:

1
2
3
4
sum=0
for n in list(range(101)):
sum=sum+n
print(sum)

循环之while 同理

1
2
3
4
5
6
sum=0
n=1
while n<101:
sum=sum+n
n=n+1
print(sum)

字典dict dictionary存储着键值对key-value,用{ }定义感觉比较像json?操作:

1
2
3
4
5
6
7
8
age={"a":20,"b":28} #初始化时设定
age["c":19] #直接放入
age["c"] #19
age["d"] #KeyError
"d" in age #false (用in方法检测key是否存在)
"d" not in age #True
age.get("d") #none dict的get方法
del age[a] #删除

方法:

1
2
3
4
5
6
7
keys() :tuple
values() :tuple
items() :tuple
clear() :None
get(key) :value
pop(key):val #删除key对应的值
update(字典) #添加键值对

注意dict的key必须为不可变对象,所以list不能作为key

字典例子:词频统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import turtle
count=10
data=[]
words=[]
yScale=6
xScale=30
def drawLine(t,x1,y1,x2,y2):
t.penup()
t.goto(x1,y1)
t.pendown()
t.goto(x2,y2)
def drawText(t,x,y,text):
t.penup()
t.goto(x,y)
t.pendown()
t.write(text)
def drawGraph(t):
drawLine(t,0,0,360,0)
drawLine(t,0,0,0,300)
for x in range(count):
x=x+1
drawText(t,x*xScale-4,-20,words[x-1])
drawText(t,x*xScale-4,data[x-1]*yScale+10,data[x-1])
drawBar(t)
def drawRectangle(t,x,y):
x=x*xScale
y=y*yScale
drawLine(t,x-5,0,x-5,y)
drawLine(t,x-5,y,x+5,y)
drawLine(t,x+5,y,x+5,0)
def drawBar(t):
for i in range(count):
drawRectangle(t,i+1,data[i])
def processLine(line,wordCounts):
line=replacePunctuations(line)
words=line.split()
for word in words:
if word in wordCounts:
wordCounts[word]+=1
else:
wordCounts[word]=1
def replacePunctuations(line):
for ch in "~@#$%^&*()_+<>?/,.:;{}[]|\"":
line=line.replace(ch," ")
return line
def main():
filename=input("enter filename").strip()
infile=open(filename,"r")
wordCounts={}
for line in infile:
processLine(line.lower(),wordCounts)
pairs=list(wordCounts.items())
items=[[x,y]for [y,x] in pairs]
items.sort() #从小到大排序
for i in range(len(items)-1,len(items)-count-1,-1): #(start,stop,step)倒着来
print(items[i][1]+"\t"+str(items[i][0]))
data.append(items[i][0])
words.append(items[i][1])
infile.close()
turtle.title("词频柱状图")
turtle.setup(900,750,0,0)
t=turtle.Turtle()
t.hideturtle()
t.width(3)
drawGraph(t)
t.exitonclick()
if __name__=='__main__':
main()

set :set是一组key的无序无重复合集,不存储value,创建set时需要list作为输入

1
2
3
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

.remove(key) .add(key)方法为set移除/添加key

2017.10.26

help() 如果输入的是python中有的对应的函数/操作,进入帮助界面,按q 退出

python的内置函数们 参考链接:https://docs.python.org/3/library/functions.html#help

ads(x)return the absolute value of x,绝对值

bin(x)return the binary string of x and preside with 0b, 将十进制数转换为二进制且以‘0b’开头

bool(x) returnTrueif x true, when x is omitted or false returnFalse

前面提到的chr()ord()字符串<->编码

filter(function,iterable),返回iterable中所有function返回true的元素

isinstance(obj, class_or_tuple, /)Return whether an object is an instance of a class or of a subclass thereof. A tuple, as in isinstance(x, (A, B, ...)), may be given as the target to

​ check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)

​ or …`` etc.

pow(x,y) x的y次幂

……太多了待学习待补充

定义函数

1
2
3
def 函数名(参数):
函数体
return

从保存的py.py文件中导入其内部定义的函数myfunc( ):

1
from py import myfunc

函数可以同时返回多个值,但实际上是一个tuple

####练习:

请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程:ax2 + bx + c = 0的两个解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import math
def quadratic(a,b,c):
if a==0:
print("a不可以为0,请重新输入")
return quadratic(int(input()),b,c)
else:
delta=b*b-4*a*c
if delta<0:
return "no solution"
else:
return (-b+math.sqrt(delta))/(2*a), (b+math.sqrt(delta))/(2*a)
print("请依次输入参数a b c")
a=int(input())
b=int(input())
c=int(input())
r=quadratic(a,b,c)
print(r)

位置参数可以说是必选参数吧,要放在最前面的。

但函数有多个函数时,可以将后几个参数设置为默认参数以简化调用,必选参数须在前,但参数不是默认值时在调用时按顺序输入即可,不按顺序时须指明 参数名=“ ”。默认参数必须是不可变对象。

可变参数 可传入个数不定的参数,在参数名前面加*就可以,随便你传入几个参数,会默认变成一个tuple。如果你已经有了一个tuple或者list,在前面加 *可以让其中每一个元素变为可变参数。例如:

关键字参数 前面**在函数内部自动形成一个dict。关键字参数可以多个,也可以直接穿入dict。例如:

1
2
3
4
5
def person(name,age,**ai):
print('name:',name,'age:',age,'other:'ai)
>>>person('Bob',24,city='Beijing')
name: Bob age: 24 other: {'city':'Beijing'}

如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收cityjob作为关键字参数。这种方式定义的函数如下:

1
2
def person(name, age, *, city, job):
print(name, age, city, job)

和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符**后面的参数被视为命名关键字参数。

2017.10.28

递归:函数内部调用本身即递归。递归次数过多时会导致栈溢出,解决办法是尾递归优化:返回一个函数而不是返回一个包含函数的算式。例如计算n的阶乘,优化前:

1
2
3
4
def nj(n):
if n==1:
return 1
return nj(n-1)*n

return中每调用一次nj就往下推一个栈,一直到n=1时才能开始一次往外推出并计算。优化:

1
2
3
4
5
6
7
def nj(n):
return njj(n,1)
def njj(num,result):
if num==1:
return 1
return njj(num-1,result*num)

这个结构就是平行的,每一次return都不需要推栈。反正尽管这么说实际上的代码也还不能做到尾优化,就一个思路看看吧。

一些好使的操作符,很js蛮像的(为什么?其实大家语言都像,但我只学过js,hhhh)

切片slice[:] 含前不含后,0可省略,负数索引倒数。

1
2
3
4
5
6
7
L=list(range(100)) #一个0-99的数字list
>>>L[10:20] #取11到20
>>>L[:10] #取前十个
>>>L[-10:] #取后十个
>>>L[:10:2] #前十个中每2个取1个 [0, 2, 4, 6, 8]
>>>L[::5] #所有数中隔5取1
>>>L[:] #复制整个list

tuple和字符串同样可以使用以上操作并返回自身切片

迭代: for…in… python中迭代不要求数据类型,只要求是可迭代对象,如何判断可迭代对象:

1
2
3
>>> from collections import Iterable
>>> isinstance('string',Iterable)
True

list、dict、string均可迭代。对于dict而言,默认对key进行迭代,若要value使用dict.values()若同时要键和值dict.items()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> dict={'a':1,'b':2}
>>> for key in dict:
... print(key)
...
a
b
>>> for value in dict.values():
... print(value)
...
1
2
>>> for n,m in dict.items():
... print(n,m)
...
a 1
b 2
>>> char='string'
>>> for n in char:
... print(n)
...
s
t
r
i
n
g

列表生成式: [ … for… in…… ]:直接看例子吧:

1
2
3
4
5
6
L=[x*x for x in range(0,5)]
L2=[x*x for x in range(0,5) if x%2==0]
L3=[(m,n) for m in range(0,5) for n in 'ABCDE']
>>> print(L3)
[(0, 'A'), (0, 'B'), (0, 'C'), (0, 'D'), (0, 'E'), (1, 'A'), (1, 'B'), (1, 'C'), (1, 'D'), (1, 'E'), (2, 'A'), (2, 'B'), (2, 'C'), (2, 'D'), (2, 'E'), (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'), (3, 'E'), (4, 'A'), (4, 'B'), (4, 'C'), (4, 'D'), (4, 'E')]

生成器 generator:和列表生成式用法相同只需将[ ]换成( )。 generator是为了节约内存而存在,它不像列表生成式一样生成完整的列表,它只是保存算法,可以一边循环一边计算,需要多少就计算多少。next() 一次计算一次,直到超出最后一个元素时抛出StopIteration的错误。

generator是可迭代对象,事实上一般使用时也是用for 循环。

还有一种方法:在函数中包含yield来定义generator,以打印斐波那契数列为例:

1
2
3
4
5
6
7
def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b #这个赋值语句是先计算好了右边b和a+b的值,再分别赋值
n=n+1
return 'done'

同步赋值语句 :x,y=y,x交换x,y的值。

每次调用next() 从上一次停止的位置开始到下一个yield结束!

练习:打印杨辉三角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def triangle():
N=[1]
while true:
yield N
N.append(0)
N=[N[i]+N[i-1] for i in range(len(N))]
i=1
for n in triangle():
print(n)
i=i+1
if i==11:
break
>>>
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

迭代器iterator,前面说的list,string,tuple,generator都是可迭代对象,但只有可以使用next() 的generator是迭代器,其他的可迭代对象通过使用iter()变成迭代器。


2017.10.30

变量可以指向一个函数:

1
2
3
f=abs
>>>f(-10)
10

高阶函数:接收了另一个函数作为参数的函数

1
2
3
4
5
def add(x,y,f):
return f(x)+f(y)
>>>add(1,-2,ads)
3

map reduce

map(函数,Iterable)对Iterable的每一个元素执行函数并返回一个Iterator,通常会再用list()处理一哈结果。

reduce(function,Iterable) 对Iterable执行函数后,用得到的结果和下一个元素执行下一次函数,是一个累加器吧! 一般返回单个值

给了个例子,自己写int函数的:

1
2
3
4
5
6
7
8
from functools import reduce
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] #这个写法是字典索引组成list吧,[]里面是key,对应取dict里的value形成list
return reduce(fn, map(char2num, s))

练习:

利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']

1
2
3
4
5
6
7
def normalize(x):
return x.lower().capitalize()
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize,L1))
print(L2)
>>>
['Adam', 'Lisa', 'Bart']

请编写一个prod()函数,可以接受一个list并利用reduce()求积:

1
2
3
4
5
6
7
8
from functools import reduce
def prod(n):
def c(x,y):
return x*y
return reduce(c,n)
print('3*4*5=',prod([3,4,5]))
>>>
3*4*5= 60

利用mapreduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from functools import reduce
def str2float(s):
n=s.index('.')
def str2nl(s):
return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'.':'.'}[s]
def f2(x,y):
return int(x*10+y)
l=list(map(str2nl,s))
l.pop(n)
return reduce(f2,l)/(10**(len(l)-n))
str='123.3456'
print(str2float(str))

还有一个别人的思路,比我的简洁明了多了!!看看别人看看你!

1
2
from functools import reduce
def str2float

filter :过滤器filter(function,Iterable) 留下function返true的元素

例子:请打印1000以内的素数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def odd_list(): #生成3开头的奇数数列
n=3
while True:
yield n
n=n+2
def prime_filter(n):
return lambda x: x%n>0 #这里的lambda是匿名函数,x是入口参数,x%n>0为函数体
def prime_ge():
li=odd_list()
while True:
n=next(li)
yield n
li=filter(prime_filter(n),li)
"""
这里写prime_filter(n)而不是prime_filter,这样就会把li中迭代的元素作为参数x.
其实这一块也可以这样写:
def prime_filter(x):
return x%n>0
def prime_ge():
li=odd_list()
while True:
n=next(li)
yield n
li=filter(prime_filter,li)
"""
for n in prime_ge():
if n<1000:
print(n)
else:
break

练习:回数是指从左向右读和从右向左读都是一样的数,例如12321909。请利用filter()滤掉非回数:

我想到的筛选方法是反转字符串,相等即可,最简单slice方法,步长为-1,直接反转

1
2
3
4
5
6
7
8
9
10
def str_filter(x):
s=str(x)
L=s[::-1]
return s==L
def is_palindrome():
return filter(str_filter,range(1,1000))
output=is_palindrome()
print(list(output))
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]

2017.11.02

排序 sortedsorted()函数可以直接接受一个list对其排序(由小到大),但也可以同时接受一个key函数,对list中的每一个元素按key返回的结果进行排序(sorted是映射函数,返回的排序list中还是原始的值哦,不是key处理过的)sorted(list,key:function)

对字符串排序是根据ASCII,所以大写字母都会比小写字母靠前,使用key=str.lower忽略大小写。

传入第三个参数reverse=True进行反向排序

练习:假设我们用一组tuple表示学生名字和成绩:

1
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

请用sorted()对上述列表分别按名字排序:

1
2
3
4
5
6
7
8
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(i):
return i[0]
LS=sorted(L,key=by_name)
print(LS)
>>>
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]

返回函数 在函数内部定义了一个函数并且返回这个函数,则形成一个闭包,类似js的,重点不在于调用函数,而在于使用其母环境

匿名函数lambda

1
2
3
>>> L=list(map(lambda x:x*x,[1,2,3])
>>> L
[1, 4, 9]

装饰器 :十一月二号 看不懂装饰器,明天再来看一定能懂,今天先不看,计划通。

十一月21号我才重新看,我反思:相当于给函数加一个外包装,在通过@该定义下调用函数,可以实现打印函数日志之类的功能。

首先,函数是一个对象/函数内部可以定义函数。装饰器一个以另一个函数为参数的函数,在装饰器内部定义一个包装函数,包装函数里面写要在调用函数qian/后执行的操作及函数调用。定义完包装函数,最后装饰器return这个包装函数。使用时@装饰器然后调用函数即可。可以给包装函数传参数,但是如果要给

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from functools import wraps
from time import time, sleep
start_time=time()
print("\n现在开始运行…\n\n*************\n")
def log(text):
def decorator(func):
@wraps(func)
def wrapers(*args,**kw): #这样写使得可以接受所有参数
print("函数{0}()即将执行,此时系统已运行了{1}秒\n".format(func.__name__,time()-start_time))
start_Time=time()
return(func(*args,**kw),print("函数{0}()执行了{1}秒之后,结束了自己\n".format(func.__name__,time()-start_Time)))[0]
return wrapers
return (decorator,print("我是一个带有参数的装饰器,我的参数是'{}'".format(text)))[0]if text.__str__()==text else decorator(text)
@log
def abc():
print("我是函数abc(),我正在执行中,不过我要睡5秒\n")
sleep(5)
@log('嘿!伙计是你吗?\n')
def efg():
print("我是函数efg(),我正在执行当中,我只想睡三秒\n")
sleep(3)
abc()
efg()
print("运行结束,一共运行了",time()-start_time)
print(abc.__name__)

上面这段运行结果如下你体会一噶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
现在开始运行…
*************
我是一个带有参数的装饰器,我的参数是'嘿!伙计是你吗?
'
函数abc()即将执行,此时系统已运行了6.771087646484375e-05秒
我是函数abc(),我正在执行中,不过我要睡5秒
函数abc()执行了5.004595041275024秒之后,结束了自己
函数efg()即将执行,此时系统已运行了5.004835844039917秒
我是函数efg(),我正在执行当中,我只想睡三秒
函数efg()执行了3.0052058696746826秒之后,结束了自己
运行结束,一共运行了 8.010263681411743
abc

关于装饰器的参数问题,我比较奇怪,是@log的时候就传参且调用log了嘛?,然后修改代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python3
from functools import wraps
from time import time, sleep
start_time=time()
print("\n现在开始运行…\n\n*************\n")
def log(text):
def decorator(func):
@wraps(func)
def wrapers(*args,**kw):
print("函数{0}()即将执行,此时系统已运行了{1}秒{2}\n".format(func.__name__,time()-start_time,text))
start_Time=time()
return(func(*args,**kw),print("函数{0}()执行了{1}秒之后,结束了自己\n".format(func.__name__,time()-start_Time)))[0]
return wrapers
return (decorator,print("我是一个带有参数的装饰器,我的参数是'{}'".format(text)))[0]if text.__str__()==text else decorator(text)
@log('try')
@log('shide')
def abc():
print("我是函数abc(),我正在执行中,不过我要睡5秒\n")
sleep(5)
@log('嘿!伙计是你吗?\n')
def efg():
print("我是函数efg(),我正在执行当中,我只想睡三秒\n")
sleep(3)
efg()
abc()
print("运行结束,一共运行了",time()-start_time)
print(abc.__name__)

结果变为: ——clearly 是的!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
现在开始运行…
*************
我是一个带有参数的装饰器,我的参数是'try'
我是一个带有参数的装饰器,我的参数是'shide'
我是一个带有参数的装饰器,我的参数是'嘿!伙计是你吗?
'
函数efg()即将执行,此时系统已运行了8.20159912109375e-05秒嘿!伙计是你吗?
我是函数efg(),我正在执行当中,我只想睡三秒
函数efg()执行了3.001433849334717秒之后,结束了自己
函数abc()即将执行,此时系统已运行了3.001613140106201秒try
函数abc()即将执行,此时系统已运行了3.0016350746154785秒shide
我是函数abc(),我正在执行中,不过我要睡5秒
函数abc()执行了5.003649950027466秒之后,结束了自己
函数abc()执行了5.003748178482056秒之后,结束了自己
运行结束,一共运行了 8.005401134490967
abc

就这教程,写的特好!看完就得会!http://www.wklken.me/posts/2013/07/19/python-translate-decorator.html 不过这个教程是用python2.4版本演示的,练习时用3.0注意print的语法

偏函数partial 是functools中的一个函数 functools.partial()用来给一些内置函数设定默认参数,使之形成新的函数直接调用。例如,设置默认按照二进制转换整数:

1
2
3
4
import functools
int2=functools.partial(int,base=2)
>>> int2('100110')
38

异常处理 try / except

先尝试try中的语句,若无异常,直接跳到try except之后的语句,若出现异常则在except中找对应的错误类型进行操作,还可以使用else(无异常执行else)和finally(不管有无异常,最后都执行finally)语句

例如一个除法:

1
2
3
4
5
6
num1=input('输入被除数:')
num2=input('输入除数:')
result=num1/num2
print('运算结果为:%d' % result)

TypeError: unsupported operand type(s) for /: 'str' and 'str' input获取的事str 不能运算

ValueError: invalid literal for int() with base 10: '' 当未input时

ZeroDivisionError: division by zero 除数为0、

Sytax Error非有效python表达式

处理后:

1
2
3
4
5
6
7
8
9
10
11
while 1:
try:
num1=int(input('输入被除数:'))
num2=int(input('输入除数:'))
result=num1/num2
except ZeroDivisionError:
print('0不能做除数\n')
except ValueError:
print('请勿输入空值或字母\n')
else:
print('运算结果为:%d' % result)

异常有那么多,不过它们都是BaseException

还有raise,当他不带参数,就会把当前错误向上抛

调试

assert 断言:

1
2
assert n!=0,'n is zero'
#这句表达式是说,n!=0这句应该为True,如果不是就回抛出 AssertionError: n is zero

logging

pdb.set_trace()设置断点,pdb调试时p查看变量c继续运行

单元测试

测试一套完整功能 一个示范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import unittest #测试模块
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def get_grade(self):
if self.score>=0 and self.score<60:
return 'C'
if self.score>=60 and self.score<80:
return 'B'
if self.score>=80 and self.score<=100:
return 'A'
else:
raise(ValueError)
class TestStudent(unittest.TestCase):
def test_80_to_100(self): #测试函数须以test_xx命名
s1 = Student('Bart', 80)
s2 = Student('Lisa', 100)
self.assertEqual(s1.get_grade(), 'A') #assertEqual用法
self.assertEqual(s2.get_grade(), 'A')
def test_60_to_80(self):
s1 = Student('Bart', 60)
s2 = Student('Lisa', 79)
self.assertEqual(s1.get_grade(), 'B')
self.assertEqual(s2.get_grade(), 'B')
def test_0_to_60(self):
s1 = Student('Bart', 0)
s2 = Student('Lisa', 59)
self.assertEqual(s1.get_grade(), 'C')
self.assertEqual(s2.get_grade(), 'C')
def test_invalid(self):
s1 = Student('Bart', -1)
s2 = Student('Lisa', 101)
with self.assertRaises(ValueError):
s1.get_grade()
with self.assertRaises(ValueError):
s2.get_grade()
if __name__ == '__main__':
unittest.main()

模块 Module

一个.py文件就是一个模块,里面可以存放写好的函数/参数等,使用时直接引用,不同模块之间的函数不用担心重名。module上面有顶package,包可以一层层的下来,只要同一个包里module不重名就可以,包.包…….py

例如我在prapy.pyz这个文件里写了一个函数叫pra,我在另一个py文件里要用它:

1
2
import prapy
prapy.pra()

顺便解释一下if__name__=='__main__':,通常会放到代码最后,因为在运行本模块时,python解释器会自动把一个特殊变量__name__置为__main__,而如果该模块是被导入到其他地方使用,该判断就会失败。也就是说我们在用命令行工具直接打开该模块时它会运行该判断下面的额外语句但当被引入其他模块时就不会,所以可以用来测试运行~


turtle库,图形绘制

绘制python蟒蛇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import turtle
def drawSnake(rad,angle,len,neckrad):
for i in range(len):
turtle.circle(rad,angle)
turtle.circle(-rad,angle)
turtle.circle(rad,angle/2)
turtle.fd(rad)
turtle.circle(neckrad+1,180)
turtle.fd(rad*2/3)
def main():
turtle.setup(1300,800,0,0)
pythonsize=30
turtle.pensize(pythonsize)
turtle.pencolor("blue")
turtle.seth(-40)
drawSnake(40,80,5,pythonsize/2)
done()
main()

一些turtle的方法:

1
2
3
4
5
6
7
turtle.setup() #打开窗口
turtle.pensize()
turtle.pencolor()
turtle.seth(角度值) #初始爬行方向,0正东,90北,180西,270南
turtle.circle #圆弧爬行 (半径位置,弧度值)
turtle.fd() #直线爬行距离
turtle.penup() #提起画笔移动到特定位置turtle.goto(x,y) 与pendown一起使用

例子:使用turtle和递归思想画tree:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from turtle import Turtle,mainloop
def tree(plist,a,l,f):
if l>5:
for p in plist:
lst=[]
p.forward(l)
q=p.clone()
p.left(a)
q.right(a)
lst.append(p)
lst.append(q)
tree(lst,a,l*f,f)
def main():
p=Turtle()
p.pencolor("green")
p.hideturtle()
p.pensize(5)
p.speed(20)
p.left(90)
p.penup()
p.goto(0,-200)
p.pendown()
tree([p],65,200,0.6375)
main()

绘制中:

再一个例子: 采用 turtle 库并使用函数封装绘制七段数码管,显示当前系统日期和时间。ipo如下:

输入:当前日期的数字形式
处理:根据每个数字绘制七段数码管表示
输出:绘制当前日期的七段数码管表示

效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import turtle
from datetime import datetime
#画线or跳过
def drawline(p,a,size):
if a:
p.pendown()
else:
p.penup()
p.fd(50)
p.right(90)
#按顺序前进画数字
def draw(p,n,size):
if n in [2,3,4,5,6,8,9]:
drawline(p,1,size)
else:
drawline(p,0,size)
if n in [0,1,3,4,5,6,7,8,9]:
drawline(p,1,size)
else:
drawline(p,0,size)
if n in [0,2,3,5,6,8,9]:
drawline(p,1,size)
else:
drawline(p,0,size)
if n in [0,2,6,8]:
drawline(p,1,size)
else:
drawline(p,0,size)
p.left(90)
if n in [0,4,5,6,8,9]:
drawline(p,1,size)
else:
drawline(p,0,size)
if n in [0,2,3,5,6,7,8,9]:
drawline(p,1,size)
else:
drawline(p,0,size)
if n in [0,1,2,3,4,7,8,9]:
drawline(p,1,size)
else:
drawline(p,0,size)
#画完一个数字,移动到下个起始位置准备
p.left(180)
p.penup()
p.fd(20)
def main():
p=turtle
p.setup(0.7,0.5)
p.pensize(2)
p.penup()
p.speed(10)
p.hideturtle()
p.setx(-400)
time=datetime.now()
for i in str(time.year):
draw(p,eval(i),50)
p.fd(30)
p.write("年",font=("微软雅黑",20,"normal"))
p.fd(50)
for i in str(time.month):
draw(p,eval(i),50)
p.fd(50)
p.write("月",font=("微软雅黑",20,"normal"))
p.fd(30)
for i in str(time.day):
draw(p,eval(i),50)
p.fd(30)
p.write("日",font=("微软雅黑",20,"normal"))
p.exitonclick()
main()

math库和random库的使用

一个例子:蒙特拉洛法计算pi值。

1
2
3
4
5
6
7
8
9
10
11
12
13
from random import random
from math import sqrt
from time import clock
DARTS=1200
hits=0
for i in range(1,DARTS):
x,y=random(),random()
dist=sqrt(x*x+y*y)
if dist<=1:
hits+=1
pi=4*hits/DARTS
print("pi的值为:%s" %pi)
print("运行时间为:%-5.5ss" %clock())

DARTS到2的30次方数量级上就基本精确了

random库的一些方法

1
2
3
4
5
6
7
8
import random
random.seed(x) #随机种子,是随机的依据,相同种子随机出的结果相同。默认是系统时间
.uniform(a,b)#a b间随机小数
.randint(a,b)#a b间随机整数
.randrange(a,b,c)#a b间随机以c递增的数
.choice(<list>)#list中随机元素
.shuffle(<list>)#打乱list
.sample(<list>,k)#list中随机k个元素

面向对象的编程

我理解的面向对象:程序里面是一个个的对象,每个对象里面包含其数据属性方法函数,而对象之间又可以互相作用(传递消息、处理),这样的过程完成一个程序的工作。而与之相对的面向程序的编程就是比较流程化的workflow,顺序执行命令的感觉

封装 继承 多态


类 class 和实例 Instance

1
2
class classsname[(父类名)]: #父类名可选,设置后继承其父类的属性和方法,如果没有合适的可以继承的类就写(object),这是所有类最后都会继承的类
[成员函数及成员变量]

初始化:构造函数__init__ 可接受int str float (两个下划线)

删除:析构函数__del__

类的属性和方法。

e.g.: 学生成绩计算 给出信息 找出gpa最高的学生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Student:
def __init__(self,name,hours,qpoints): #构造函数的第一个参数代表类本身 名字随意
#定义对象的属性
self.name=name
self.hours=float(hours)
self.qpoints=float(qpoints) #强制转换float 便于计算
#定义对象的方法,同定义函数,第一个参数需为self
def getName(self):
return self.name
def getHours(self):
return self.hours
def getQpoints(self):
return self.qpoints
def gpa(self):
return self.qpoints/self.hours
def makeStudent(infoStr): #创建类的实例 类名+()
name,hours,qpoints=infoStr.split("\t")
return Student(name,hours,qpoints)
def main():
filename=input("enter name the grade file:")
infile=open(filename,"r")
best = makeStudent(infile.readline()) #先默认将第一个学生设置为best
for line in infile:
s=makeStudent(infile.readline())
if s.gpa()>best.gpa():
best=s
infile.close()
print("The best student is",best.getName())
print("Hours:",best.getHours())
print("gpa:",best.gpa())
if __name__=='__main__':
main()

面向对象的编程 与类息息相关

特点之 封装 多态(对象怎样回应消息——同一函数启用不同方法,⏰灵活性)。继承(借用另一个类的方法,避免操作重复,提升代码的复用程度)

访问限制

按照以上方法,可以在外部访问并修改实例的参数的值,为了起到保护作用,可以在命名时在前面添加两个下划线 name 变为__name 就成为了私有变量,在外部不可以访问,若要取得其值可以在内部定义getName方法

继承与多态

前面讲过在定义类时可以同时定义(父类名),该类自动拥有父类的所有功能,可以直接和本类的功能一样调用,此为继承。

如果在子类中重新定义了新的和父类相同的方法,调用时会自动调用子类中新定义的,此为多态。同时,我们在定义类时相当于是新定义了一种类型,其所有实例都是这种类型。子类的类型即是子类,也是父类。一个应用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Animal:
def run(self):
print("Animal is running")
class Cat(Animal):
pass
class Dog(Animal): #定义类
def run(self):
print("Dog is running")
animal=Animal()
cat=Cat()
dog=Dog() #创建类的实例
animal.run()
cat.run()
dog.run()
def myrun(animal):
animal.run()
myrun(animal)
myrun(cat)
myrun(dog)
//运行结果:
Animal is running
Animal is running
Dog is running
Animal is running
Animal is running
Dog is running

获取对象信息

  1. type() 返回参数的的Class类型

    1
    2
    3
    4
    5
    type(123)==type(456) //True
    type('abc')==str //True
    type(abs) //
    <type 'builtin_function_or_method'>

  2. isinstance() 方便检测有继承关系的类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #有如下继承关系 object->Animal->Dog->Husky
    a=Animal()
    b=Dog()
    c=Husky()
    isinstance(c,Husky) //True
    isinstance(c,Dog) //True
    isinstance(b,Husky) //False
  3. dir()获得一个对象的所有属性和方法,返回的是一个包含的字符串list

    使用getattr()setattr()以及hasattr(),我们可以直接操作一个对象的状态:(attribute 属性)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class MyObject(object):
    def __init__(self):
    self.x=9
    def power(self):
    return self.x*self.x
    obj=MyObject()
    >>> hasattr(obj, 'x') # 有属性'x'吗?
    True
    >>> obj.x
    9
    >>> hasattr(obj, 'y') # 有属性'y'吗?
    False
    >>> setattr(obj, 'y', 19) # 设置一个属性'y'
    >>> hasattr(obj, 'y') # 有属性'y'吗?
    True
    >>> getattr(obj, 'y') # 获取属性'y'
    19
    >>> obj.y # 获取属性'y'
    19
    >>> hasattr(obj, 'power') # 有属性'power'吗?
    True
    >>> getattr(obj, 'power') # 获取属性'power'
    <bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
    >>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
    >>> fn # fn指向obj.power
    <bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
    >>> fn() # 调用fn()与调用obj.power()是一样的
    81

实例的属性和类属性

我们经常给实例绑定属性,如果是类本身绑定属性,直接在class中定义类属性,其所有实例可访问,

使用__slots__

python是动态语言,我们很容易给class及其实例加上功能,用slots限制实例的属性:

1
2
class Student(object):
__slots__=('name','age') #元组定义允许绑定的属性名称

__slots__ 仅对当前类的实例有效,对其子类的实例无效,但如果在子类中定义了__slots__,该子类的实例允许定义的属性就是两者之和。

定制类

__xxx__的变量/函数是有特殊用途的。上面讲了__slots__

__str____repr__: 是用于打印显示更友好的信息print

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Before:
def __init__(self,name):
self.name=name
class After:
def __init__(self,name):
self.name=name
def __str__(self):
return 'Student object(name:%s)'%self.name
print(Before('Bob'))
print(After('Bob'))
//结果如下
<__main__.Before object at 0x10c8749b0>
Student object(name:Bob)

但是在交互模式/命令行下,程序员输入After('Bob')仍然会显示<__main__.After object at xxxxxxxxx>

__repr__就是面向程序员的,和__str__同用法,或者直接在后面加上__repr__=__str__

__iter__ :用于类想的for in迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Fib(object):
def __init__(self):
self.a,self.b=0,1
def __iter__(self):
return self #__iter__方法返回一个迭代对象,这里就是它自己;之后循环会自动调用该迭代对象的__next__方法得到循环的下一个值,直到遇到StopIteration
def __next__(self):
self.a,self.b=self.b,self.a+self.b
if self.a>10000:
raise StopIteration()
return self.a #返回下一个值
#运行试试
for n in Fib():
print(n)
//
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765

__getitem__但iter吧就只能这么迭代算出结果,并不是保留了这些结果的list,你要Fib()[5]是搞不成的,用__getitem__方法就可以

__getattr__ 调用了不存在的属性时会调用这个方法,所以他吗有什么用???哦,动态属性可以搞

__call__ 调用实例本身,可以用callable()函数判断对象是否是可调用对象(返回True or False)

使用@property

可以把一个方法变成属性调用。解决什么问题?:给实例直接绑定属性赋参数就没办法检查,但如果把检查参数的代写到一个专门set参数值的函数里又比较麻烦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Student(object):
@property #把getter方法变成属性
def __init__(self):
return self._score
@score.setter #新建装饰器,把setter方法变成属性赋值
def score(self,value):
if not isinstance(value,int):
raise ValueError('score must be an integer')
#raise是用来强行自定义例外的语句
if value<0 or value>100:
raise ValueError('score must between 0~100')
self.score=value
>>>s=Student()
>>>s.score=60 # setter: s.set_score(60)
>>>s.score # getter: s.get_score
60
>>>s.score=9999
Traceback (most recent call last):
...
ValueError:'score must between 0~100'

使用枚举类Enum

类似月份这种枚举常量,python提供了Enum这个class,对于每一个常量引用一个实例

1
2
3
4
5
from enum import Enum
Month=Enum('Month',('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
#Month类型的枚举类,成员的value自动从1(int)开始赋的
Month.Jan #引用常量

使用元类

  1. type()动态创建class对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def fn(self,name='world'): #定义要使用的函数
    print('Hello,%s.'%name)
    Hello=type('Hello',(object,),dict(hello=fn)) #创建Hello类
    #type的三个参数:class名称/父类集合tuple(这里只有一个父类 tuple的单元素写法)/将已创建的函数与class的方法绑定
    h=Hello()
    h.hello()
    print(type(h))
    print(type(Hello))
    //
    Hello,world.
    <class '__main__.Hello'>
    <class 'type'>
  2. metaclass元类

    类的类??

多重继承

按照分类设计不同的父类,子类可以同时继承多个父类


IO编程

文件操作

:打开文件 open(参数1,参数2) 参数1是打开文件的全名,参数2是打开方式。(文件存在则打开,不存在抛出IOError

1
2
3
4
file_obj=open("prapy.py","wb") #(r只读/w只写/a附到文件末尾/rb只读二进制/wb/r+读写)
read() #文件的所有内容 字符串
readline() #返回下一行 字符串
readlines() #文件的所有内容 列表(每项是以换行符结尾的字符串)

写入文件write()

writelines() 针对列表,接受字符串列表参数并写入, 不会自动写入换行

文件遍历:模版如下

1
2
3
4
file=open(文件名,"r")
for line in file.readlines():
#处理一行文件内容
file.close() #使用后必须关闭文件

例子:拷贝文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def main():
f1=input("enter a source file").strip()
f2=input("enter a source file").strip()
infile=open(f1,"r")
outfile=open(f2,"w")
countLines=countChars=0
for line in inflie:
countLines+=1
countChars+=len(line)
outfile.write(line)
print(countLines,"lines and",countChars,"chars copied")
infile.close()
outfile.close()
main()

多文件读写 :例子:将两个文件合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#打开 读取文件
ftele1=open('TeleAddressBook.txt','rb')
ftele2=open('EmailAddressBook.txt','rb')
ftele1.readline()
ftele2.readline() #跳过表头
lines1=ftele1.readlines()
lines2=ftele2.readlines()
list1_name = []
list1_tele = []
list2_name = []
list2_email = []
for line in lines1:
elements=line.split()
list1_name.append(str(elements[0].decode('gbk')))
list1_tele.append(str(elements[1].decode('gbk')))
for line in lines2:
elements=line.split()
list2_name.append(str(elements[0].decode('gbk')))
list2_email.append(str(elements[1].decode('gbk')))
#合并处理
lines=[]
lines.append('姓名\t 电话 \t 邮箱\n') #新表头
for i in range(len(list1_name)):
s=''
if list1_name[i] in list2_name:
j=list2_name.index(list_name[i])
s='\t'.join([list1_name[i],list1_tele[i],list2_email[j]])
s+='\n'
else:
s = '\t'.join([list1_name[i], list1_tele[i], str(' ----- ')])
s += '\n'
lines.append(s)
for i in range(len(list2_name)):
s=''
if list2_name[i] not in list1_name:
s = '\t'.join([list2_name[i], str(' ----- '), list2_email[i]])
s += '\n'
lines.append(s)
ftele3=open('AddressBook.txt','w')
ftele3.writelines(lines)
ftele3.close()
ftele1.close()
ftele2.close()
print("finished")

文件循环

1
2
3
inflie=open(fileName,"r")
line=inflie.readline() #读取行
for i in line.spilt(",") #读取行中数字

StringIO:在内存中读取str

os模块操作文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>>import os
>>>os.name #操作系统名字
'posix'
>>>os.uname() #操作系统详细信息
>>>posix.uname_result(sysname='Darwin', nodename='littlewhitedeMacBook-Pro.local', release='17.2.0', version='Darwin Kernel Version 17.2.0: Fri Sep 29 18:27:05 PDT 2017; root:xnu-4570.20.62~3/RELEASE_X86_64', machine='x86_64')
>>>os.environ #获取完整环境变量
environ({'TERM_PROGRAM': 'Apple_Terminal', 'SHELL': '/bin/bash', 'TERM': 'xterm-256color', 'TMPDIR': '/var/folders/j9/8hg637r53sd81jtt8km0n0xc0000gn/T/', 'Apple_PubSub_Socket_Render': '/private/tmp/com.apple.launchd.HWmwomf0aM/Render', 'TERM_PROGRAM_VERSION': '400', 'TERM_SESSION_ID': '5D5FD93A-46C5-497E-9633-C13D908C0211', 'USER': 'zeromeme', 'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.f6Ml37ah1v/Listeners', 'PATH': '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin', 'PWD': '/Users/zeromeme', 'LANG': 'zh_CN.UTF-8', 'XPC_FLAGS': '0x0', 'XPC_SERVICE_NAME': '0', 'SHLVL': '1', 'HOME': '/Users/zeromeme', 'LOGNAME': 'zeromeme', '_': '/usr/local/bin/python3', '__CF_USER_TEXT_ENCODING': '0x1F5:0x19:0x34', '__PYVENV_LAUNCHER__': '/usr/local/bin/python3'})
>>>os.path #
<module 'posixpath' from '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/posixpath.py'>
>>>os.mkdir('/Users/zeromeme/newset') #创建新目录
>>>os.rmdir('/Users/zeromeme/newset') #删除目录
#合并拆分路径
os.path.join()
os.path.split()
os.rename('','') #重命名文件

序列化

变量 从内存中变成可存储的过程 pickling 反序列化unpickling

1
2
3
4
import pickle
d=dict(name='Bob',age=20,score=88)
pickle.dumps(d) # 吧任意对象序列化成一个bytes
pickle.loads() #反序列化出对象

使用dump()方法的话这样写序列化对象后直接写入 file-like Object:

1
2
3
f=open('dump.txt','wb')
pickle.dump(d,f)
f.close

序列化为JSON

json嘛,js里面的标准对象类型,{} dict []list

1
2
3
4
5
import json
d=dict(name='Bob',age=20,score=88)
json.dumps(d) #序列化为标准json的str
//'{"age":20,"score":88,"name":"Bob"}'
#loads() dump() load() 方法同理
1
2
3
4
>>> print(json.dumps(s, default=student2dict)) #s是类的实例,无法直接转换,使用可选参数default并传入将class实例转换为dict的函数即可
{"age": 20, "name": "Bob", "score": 88}
//也可以写 default=lambda odj:odj.__dict__

进程和线程

多任务-进程Process 任务的多子任务-线程

?我不太明白在讲什么?系统调用 进程任务