TouchMyTeeth

你的牙仔


  • 首页

  • 关于

  • 标签

  • 分类

  • 目录

2018.9.17

发表于 2018-09-17 | 分类于 日常 |

三点半的感觉是沉重且清醒啊

我过了将近一年的时间没有使用hexo,刚刚在想以前做过的事,于是翻电脑看到blog的文档,我现在写的这些也不是想表达什么,只是想作为一个突然冒出的存活卡,打一下,在互联网世界里留一下痕迹,然后再下一次想起来用hexo的时候我就会说哇上一次写2018年9月。想起来又是一件没有坚持下去的事情。
不是抑郁也不躁郁
觉得人类值得一个灭绝

PYTHON笔记本

发表于 2017-11-05 | 分类于 notebook |

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'}

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

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

利用map和reduce编写一个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

练习:回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用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

排序 sorted :sorted()函数可以直接接受一个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 任务的多子任务-线程

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

笔记:Bootstrap框架

发表于 2017-09-29 |

Bootstrap响应框架

最大的用处是根据屏幕大小调整html元素

首先里面放上:

1
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.1/css/bootstrap.min.css"/>

给元素指定class可以自动完成一些内容:

对于图片: class=“img-responsive” 可以自动调节大小适应环境

对于文字: class=“text-center”可以居中

对于按钮: class=“btn” bootstrap风格的按钮

btn-block 使按钮成为块级元素 btn-primary/info/danger依次是深蓝 浅蓝 红色 img

12列网格布局

bootstrap的重点就是这个吧

img

使用举例:将要使用网格布局的部分放在class为“row”的div中,之后每列按所需大小依次放入class为“col-md-数字”的div中(Col-md-数字中md表示medium,数字是所占列宽;Col-xs-数字可以应用于较小的屏幕 extra small)

1
2
3
4
<div class=”row”>
<div class=”col-xs-6”> <p></p> </div>
<div class=”col-xs-6”> <p></p> </div>
</div>

FontAwesome矢量图标库

FontAwesome最初就是为Bootsrap框架设计的

在html头部加入:

1
2
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/font-awesome.min.css">

html-notebook

发表于 2017-09-23 |

##笔记:HTML&CSS基础##

七月的时候跟着@陈斌儿童编程和机器人的程序媛计划开始学习编程,在这之前是一个学会计的没有梦想的咸鱼,真的很幸运当初报名了这个计划,感谢斌叔可以说是无私的付出了!coding is interesting!

我的学习资源:

  1. 程序媛计划的课程:https://www.cxy61.com/girl/app/home/home.html
  2. 《HTML&CSS设计与构建网站》google drive分享链接:https://drive.google.com/open?id=0Bzo_0SqaeHqcWFpPWW80R0VSdk0
  3. FreeCodeCamp的教程:https://www.freecodecamp.org/
不是教程是笔记,不太有逻辑性,我觉得简单的懒就不记了

HTML是啥

HTML是一种超文本标记语言,它不是一种编程语言,而是一种标记语言,用来描述网页。我们用HTML配合CSS即javascript等其他语言配合写出的html文档被web浏览器读取出来就是网页。HTML包含标签和纯文本,可以看作是网页中的静态部分。

用什么写HTML?

任何文本编辑器都可以写Html,我用了sublime,属于代码编辑器,后面写css和javascript也可以直接用它,好使! 戳这里直接下载

打开sublime并将文件后缀名改为.html保存就生成了网页,打开该文档就可以看到你写的html变成网页的样子

属性

  1. 全局属性

    Class 类同一元素添加多个类,中间空格

    id 就id呗

    style 行内样式

    contenteditable: true/ false 可否编辑

    draggable: true/false/auto 可否拽动

    title=“ ” 额外信息,鼠标悬停显示

    type 类型 例如=“placeholder”占位符

  2. 事件属性

    鼠标:onclick ondbclick

常用标签

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!DOCTYPE html>
    <html>
    <head> //头部
    <meta charset="UTF-8"> //中文可编译
    <style></style> //css层叠样式表
    <script></script> //js
    <head>
    <body>
    //内容
    </body>
    </html>

    ​

  2. 标题 heading,h1字体最大,依次减小

    1
    2
    <h1>heading1</h1>
    <h2>heading2</h2>

    heading1

    heading2

  3. <hr/>分割线

    <p> </p>段落正文

    <i> </i>斜体 <b> </b>粗体

    <sup> </sup> 上标 <sub> </sub>下标

    举例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    </head>
    <body>
    <h1>example</h1>
    <p>正常<b>粗体</b><i>斜体</i><sup>上标</sup></p>
    <br/>
    </body>
    </html>

  4. <img src="url">图片

  5. <a href="url" target="-blank">text</a>链接

    属性target打开目标 -blank为在新窗口打开

    url可以写#id,链接到页面中的对应id元素

  6. <div> </div>分块

  7. 表单 <form></form>

    action=”url” 接受的url

    单行文本框/密码/单选按钮/复选按钮<input type="text/password/radio/checkbox"> </input>

  8. ​

html好简单啊

我不想写了……感觉都不用整理啊这些,我记一点我觉得难的好了

CSS的使用

  1. 使用外部css:写好单独的css文件后,在内加入,好处是一个文件可以直接引用到多个html文件一起用
  2. 在内部,内联表,使用css选择器,方便
  3. html标签内

CSS的属性们

常用
属性 属性值
color 1. 直接上名称:white/red/black/blue 2. rgba(0-255,0-255,0-255 ,0.0-1.0 ),前三个数对应r/g/b值越大越多,a是透明度 1.0完全透明 3. hex code:#123456 六个数字中每两位依次表示rgb值,十六进制(0-9 A-F),越大越多
background-color/image/repeat/attachment/position 颜色/图像:”url”/重复方式:repeat(水平垂直重复)repeat-x(水平重复)repeat-y(垂直重复)no-repeat(不重复)/滚动时图像的移动方式fixed scroll/对不重复的背景图像指定位置
height/width 高/宽。具体数值px
float 使普通流中的元素浮动——尽可能地靠左/右排列:left/right
clear 清除浮动,清除左/右/两边均不接触/均可接触元素:left/right/both/none
position static
文本
属性 属性值说明
font-size 值px/?%(设置了默认大小时可用百分比)/ ?em(?个m的宽度)
font-family serif衬线 sans-serif无衬线 monospace等宽
text-transform 大小写 uppercase大写 lowercase小写 capitalize首字母大写
text-align 对齐方式:center/left/right/justify
line-height 行间距: 一般是1.4~1.5em
text-decoration underline下划线 overline顶部线 line-through穿过文字
Text-text-shadow 文本投影 ?px(左)?px(上下)?(模糊度)#232673 (颜色)
div盒子
属性 属性值
min/max-width/height 宽高限制
border-width/style/color style: solid/dotted/dashed等
margin-top/right/bottom/left 外距离,简写时顺序 上右下左
border-radius 边框半径 变圆角
padding 内边距,用法同margin
display 块级元素与内联元素的转换:inline(块->内) block(内->块) none(隐藏) Inline-block(行内块级元素)
overflow 当内容溢出div时: hidden(隐藏), scroll(滚动)

CSS选择器

通用:

选择器 选择对象
*{ } 所有元素
h1{ } 所有

.note{ } class为note的所有元素
p.note{ } class为note的所有

元素

#intro{ } id为intro 的元素
li>a{ } 所有父元素为
  • 的元素
  • p a{ } 所有位于

    中的 元素

    h1+p{ } 位于

    后的第一个

    元素

    css样式冲突时的优先顺序原则:

    1. 内联表中,对于两个相同的选择器,后面的优先
    2. 更具体的更优先,例如h1优先于*; p.note 优先于.note
    3. 重要性: 将 !important 添加到属性值中,优先级最高
    伪元素/伪类

    状态类,元素处于某个状态时的样式,响应用户

    效果
    :hover { } 光标悬停
    :active { } 被激活的元素
    :focus { } 被选中的元素
    :first-letter { } 元素的第一个字母
    :first-child { } 元素的第一个字元素
    :link { } 未被访问的链接
    :visited { } 已被访问的链接

    ……

    to be updated

    Have a try:mac上搭建hexo!

    发表于 2017-09-22 | 分类于 教程 |

    mac上如何搭建hexo

    刚刚开始学coding相关,因为想要整理学习笔记而萌生了写博客的念头,发现了hexo这个好看好玩又好用的静态框架,于是开始尝试,折腾了好半天终于简单的搞起来了 :https://zeromeme.github.io/。
    以下是我一个啥也不知道的小白鼓捣的全过程,写的也比较白痴,遇到很多报错,google了很多解决办法,尝试了很多不同的命令,我写的是我印象中最终成功的命令,所以不保证照着我的步骤就能顺利搭成功哦,还是要善用google!

    更新日期:2017.9.20

    mac版本:10.12.6

    先整理一下思路:注册github账户—安装git—安装node.js—安装hexo—本地配置—生成发布—(配置主题)

    注册GitHub

    https://github.com/

    git

    AppStore安装Xcode,Xcode自带git,老教程里有人说安装Xcode之后需要注意里面再安装命令行工具(command line tools),但我安装Xcode之后打开发现已经安装好命令行工具了。

    检测git是否安装成功:mac打开终端输入如下命令

    1
    git --version

    成功就会出现版本号。

    设置个人信息:你的github账户名及注册邮箱

    1
    2
    git config --global user.name "xxx”
    git config --global user.email "xxx@xxx.com"

    node.js

    进入官网https://nodejs.org/en/下载node.js

    我下载的是最新版for mac v8.5.0

    下载之后按照提示一路安装就好。

    检测node.js是否安装成功

    1
    node -v

    安装Hexo

    使用命令:

    1
    npm install -g hexo-cli

    安装时出现了以下报错:

    npm WARN deprecated swig@1.4.2: This package is no longer maintained

    我没管它,也没有对之后的步骤产生影响。

    创建hexo文件夹并cd到该位置,或者在该位置右键git bash

    例如:我安装到我自己user下的blog文件夹里

    1
    cd ~zeromeme/blog

    初始化:

    1
    hexo init

    安装server:

    1
    npm install hexo -server --save

    安装npm:

    1
    npm install

    安装好后可以用一下命令检测,出现版本号则成功:

    1
    npm -v

    开启hexo 服务器:

    1
    hexo s

    在浏览器打开 localhost:4000 出现以下页面就说明你前面的步骤都成功啦!开心哇!

    添加SSH-Key

    生成SSH:(邮箱为自己的github账号)

    1
    ssh-keygen -t rsa -C "xxxx@xxx.com"

    会要求你连续输三次密码进行设置,可以按三次回车设置密码为空

    打开id_rsa.pub 所在文件夹:

    1
    2
    ls
    open id_rsa.pub

    打开并复制该文件,进入https://github.com/settings/keys Add SHH粘贴并保存,

    创建新repo:

    Repository name的命名固定格式:yourname.github.io

    yourname是你的github账户名字

    本地配置

    打开你创建的for hexo的文件夹找到_config.yml文件,打开编辑:(把zeromeme换成你自己的账户名哦)

    1
    2
    3
    4
    deploy:
    type: git
    repository: git@github.com:zeromeme/zeromeme.github.io.git
    branch: master

    注意正确使用空格缩进,且三个冒号后面都要有一个空格。

    (如果后续运行不正确,终端会提示哪一行出错的,例如:

    1
    JS-YAML: incomplete explicit mapping pair; a key node is missed at line 18, column 29:last_updated: Last updated: %s

    回去改line18 column29就好啦)

    本地运行并查看:(请cd到正确的位置哦)

    1
    2
    3
    cd ~zeromeme/blog
    hexo g
    hexo d

    打开https://zeromeme.github.io/ (换成自己用户名),希望你成功了!

    开始写吧

    cd到你的hexo文件夹,then

    1
    hexo new "标题"

    在 source/_posts 里就会产生该文件,用你喜欢的Markdown编辑器开始写吧!

    Markdown编辑器推荐——Typora

    https://typora.io/

    mac os目前还是byte版,免费,页面简洁,除了基本功能,插入代码和图片也都非常方便。

    发布文章

    1
    2
    3
    cd ~zeromeme/blog //cd到正确的位置
    hexo g //生成
    hexo d //部署

    更改Hexo主题

    Hexo有超多主题可以换,https://hexo.io/themes/,感谢各位贡献者!

    我用了Next,很多人用各种插件很全的一个主题

    http://theme-next.iissnan.com/getting-started.html

    next主页里的教程写的非常详尽了我就不重复了。


    谢谢观看,祝明天开心

    Hello World

    发表于 2017-09-17 | 分类于 日常 |

    Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

    Quick Start

    Create a new post

    1
    $ hexo new "My New Post"

    More info: Writing

    Run server

    1
    $ hexo server

    More info: Server

    Generate static files

    1
    $ hexo generate

    More info: Generating

    Deploy to remote sites

    1
    $ hexo deploy

    More info: Deployment

    我想说的

    前两天整理文件觉得自己记的笔记太混乱了,萌生了整理笔记并记录到博客的想法,在网上转了一圈觉得hexo好看简洁棒!于是动手开始搞,而我还只是一个刚刚接触coding没多久的人,零零散散几十个小时,对着教程里看不懂的指令一步步照做,遇到无数error,踩了无数的坑,折腾了两天终于有了现在的这一篇fisrt try。

    过程中看了各种出自不同人之手的教程,google了无数个错误,慢慢的也把整个思路和指令的具体含义搞懂了,也大概明白了自己一开始的错误,接下来的第一篇就写一下我搭hexo的过程吧!

    zeromeme

    zeromeme

    不如掀了这桌麻将一起听听海浪/whatever/just for fun

    6 日志
    3 分类
    5 标签
    GitHub Twitter 微博
    © 2018 zeromeme
    由 Hexo 强力驱动
    |
    主题 — NexT.Pisces v5.1.2