Little H title

this is subtitle


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 公益404

python环境安装

发表于 2018-11-25 | 分类于 python教程

python 环境安装

下一个thonny先用着,

在 mac 上安装 python, 就是用brew install python3 然后启动格式 python3 而不是 python

基本语法

print(), 字符串+, 但只能串和串, 这里和 int 这种数学的

+-*/%
** 幂

变量小写,不用声明, 用_隔开.直接赋值好了, 定义多个变量用a,b,c=11,12,13, 注意如果是 a=1,2 这个是 tuple. #是注释 “”” “””是块

变量

变量不用声明, 直接用. 有 int float bool string

有函数 function, tuple, list, dict

类 class 是 type

1
print(type(a)) # 看类型

循环 while 和 for, 没有括号, 只有缩进

1
2
while True:
print("I'm True")

True, False. None

在 Python 中集合类型有 list、 tuple 、dict 和 set 等, 都能迭代.

1
2
3
4
5
6
7
8
a = range(10)
while a:
print(a[-1])
a = a[:len(a)-1]


for item in sequence: # 序列哦
expressions

1 range(start, stop) [start, stop)
2 range(stop)
3 range(start, stop, step)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
list []

tuple 类型 ()
tup = ('python', 2.7, 64)
for i in tup:
print(i)

dictionary 类型 {}
dic = {}
dic['lan'] = 'python'
dic['version'] = 2.7
dic['platform'] = 64
for key in dic:
print(key, dic[key])

set 类型
s = set(['python', 'python2', 'python3','python'])
for item in s:
print(item)

迭代器 __iter__ 和 __next__ 生成器 yield

跳出循环, pass, break, continue

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
a=True
while a:
b= input('type somesthing')
if b=='1':
a= False
else:
pass # 这是啥事不干, 只是占个位, 还是继续下个循环, 但continue会跳过后面的print
print('still in while')
print ('finish run')

# type somesthing44
# still in while
# type somesthing3
# still in while
# type somesthing2
# still in while
# type somesthing1
# still in while
# finish run

while True:
b= input('type somesthing:')
if b=='1':
break
else:
pass
print('still in while')
print ('finish run')

"""
type somesthing:4
still in while
type somesthing:5
still in while
type somesthing:1
finish run
"""

while True:
b=input('input somesthing:')
if b=='1':
continue
else:
pass
print('still in while' )

print ('finish run')
"""
input somesthing:3
still in while
input somesthing:1 # 没有"still in while"。直接进入下一次循环
input somesthing:4
still in while
input somesthing:
"""

if, if else 和 if elif

1
2
3
4
if condition:
true_expressions
else:
false_expressions

没有 condition ? value1 : value2 三目操作符, 用:

1
var = var1 if condition else var2

def 函数 是函数哦

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
def function_name(parameters):
expressions

调用时换参数位置, 但指定
func(b=2,a=1)是同样的 的效果

默认参数
def sale_car(price, color='red', brand='carmy', is_second_hand=True):

自调用, 不晓得
if __name__ == '__main__':
#code_here

可变参数, 可迭代的grades对象
def report(name, *grades):
total_grade = 0
for grade in grades:
total_grade += grade
print(name, 'total grade is ', total_grade)

report('Mike', 8, 9, 10)
# Mike total grade is 27

关键字参数, 自动封装成一个字典(dict)
def portrait(name, **kw):
print('name is', name)
for k,v in kw.items():
print(k, v)

portrait('Mike', age=24, country='China', education='bachelor')

# name is Mike
# age 24
# country China
# education bachelor

通过可变参数和关键字参数,任何函数都可以用 universal_func(*args, **kw) 表达。

return 可以返回多个值,以逗号分隔。相当于返回一个 tuple(定值表)。
return a,b,c # 相当于 return (a,b,c)

lambda

lambda 定义一个简单的函数,实现简化代码的功能,看代码会更好理解。

fun = lambda x,y : x+y, 冒号前的 x,y 为自变量,冒号后 x+y 为具体运算。

1
2
3
4
5
6
7
8
9
10
fun= lambda x,y:x+y
x=int(input('x=')) #这里要定义int整数,否则会默认为字符串
y=int(input('y='))
print(fun(x,y))

"""
x=6
y=6
12
"""

map

map 是把函数和参数绑定在一起。一对一对.

1
2
3
4
5
6
7
8
9
10
>>> def fun(x,y):
return (x+y)
>>> list(map(fun,[1],[2]))
"""
[3]
"""
>>> list(map(fun,[1,2],[3,4]))
"""
[4,6]
"""

全局和局部, 同 javascript, 在函数中的就是局部

用 global 关键字在局部作用域中改这个全局同名变量

1
2
3
4
5
6
7
8
9
10
11
APPLY = 100 # 全局变量
a = None
def fun():
global a # 使用之前在全局里定义的 a
a = 20 # 现在的 a 是全局变量了
return a+100

print(APPLE) # 100
print('a past:', a) # None
fun()
print('a now:', a) # 20

python 单下划线及双下划线使用总结

类 class

按变量, 函数的定义, 从 js 理解, 反正也是类. 没有 this 但有 self

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
class Calculator:       #首字母要大写,冒号不能缺
name='Good Calculator' #该行为class的属性
price=18
def add(self,x,y): # self
print(self.name)
result = x + y
print(result)
def minus(self,x,y):
result=x-y
print(result)
def times(self,x,y):
print(x*y)
def divide(self,x,y):
print(x/y)

"""
>>> cal=Calculator() #注意这里运行class的时候要加"()",否则调用下面函数的时候会出现错误,导致无法调用.
>>> cal.name
'Good Calculator'
>>> cal.price
18
>>> cal.add(10,20)
Good Calculator
30
>>> cal.minus(10,20)
-10
>>> cal.times(10,20)
200
>>> cal.divide(10,20)
0.5
>>>
"""

class Human(object):
laugh = 'hahahaha'
def show_laugh(self):
print self.laugh
def laugh_100th(self):
for i in range(100):
self.show_laugh()

li_lei = Human()
li_lei.laugh_100th()

它的参数中有一个self,它是为了方便我们引用对象自身。方法的第一个参数必须是self,无论是否用到。有关self的内容会在下一讲展开
在定义方法时,必须有 self 这一参数。这个参数表示某个对象。对象拥有类的所有性质,那么我们可以通过 self,调用类属性。

这里有一个类属性 laugh。在方法 show_laugh()中,通过 self.laugh,调用了该属性的值。
还可以用相同的方式调用其它方法。方法 show_laugh(),在方法 laugh_100th 中()被调用。
通过对象可以修改类属性值。但这是危险的。类属性被所有同一类及其子类的对象共享。类属性值的改变会影响所有的对象

用 __init__() 初始化, 当然也可以放初始值.Python 会自动调用这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Calculator:
name='good calculator'
price=18
def __init__(self,name,price,height,width,weight): # 注意,这里的下划线是双下划线
self.name=name
self.price=price
self.h=height
self.wi=width
self.we=weight
"""
>>> c=Calculator('bad calculator',18,17,16,15) # 这里传入
>>> c.name
'bad calculator'
>>> c.price
18
>>> c.h
17
>>> c.wi
16
>>> c.we
15
>>>
"""

子类继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Bird(object): # (括号中的object,当括号中为object时,说明这个类没有父类(到头了))
have_feather = True
way_of_reproduction = 'egg'
def move(self, dx, dy):
position = [0,0]
position[0] = position[0] + dx
position[1] = position[1] + dy
return position

summer = Bird()
print 'after move:',summer.move(5,8)

class Chicken(Bird): # 不是用extends 而是传入Bird这个
way_of_move = 'walk'
possible_in_KFC = True

class Oriole(Bird):
way_of_move = 'fly'
possible_in_KFC = False

summer = Chicken()
print summer.have_feather
print summer.move(5,8)

元组 Tuple 列表 List 统称为 sequence(序列)是一组有顺序的元素的集合

  1. tuple 元素不可变,list 元素可变
  2. 序列的引用 s[2], s[1:8:2]
  3. 字符串是一种 tuple

开始

或者说对象集合

tuple 和 list 的主要区别在于,一旦建立,tuple 的各个元素不可再变更,而 list 的各个元素可以再变更。

Tuple
叫做 tuple,用小括号、或者无括号来表述,是一连串有顺序的数字。

1
2
a_tuple = (12, 3, 5, 15 , 6)
another_tuple = 12, 3, 5, 15 , 6

字符串是一种特殊的 tuple, 因此可以执行元组的相关操作

List
而 list 是以中括号来命名的:

1
a_list = [12, 3, 67, 7, 82]

可以用 range() len()

range() 这个函数的功能是新建一个表。这个表的元素都是整数,从 0 开始,下一个元素比前一个大 1, 直到函数中所写的上限 (不包括该上限本身)

list 是一个类, 是 Python 已经定义好的一个类, 通过print(dir(list)) 和 help 来查看, 有方法. 运算符都是特殊方法

序列都可以用[]来引用

还有见到用[:]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
范围引用: 基本样式[下限:上限:步长]

>>>print(s1[:5]) # 从开始到下标4 (下标5的元素 不包括在内)

>>>print(s1[2:]) # 从下标2到最后

>>>print(s1[0:5:2]) # 从下标0到下标4 (下标5不包括在内),每隔2取一个元素 (下标为0,2,4的元素)

>>>print(s1[2:0:-1]) # 从下标2到下标1

从上面可以看到,在范围引用的时候,如果写明上限,那么这个**上限本身不包括在内**。

尾部元素引用

>>>print(s1[-1]) # 序列最后一个元素

>>>print(s1[-3]) # 序列倒数第三个元素

同样,如果s1[0:-1], 那么最后一个元素不会被引用 (**再一次,不包括上限元素本身**)

List

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
插入
a = [1,2,3,4,1,1,-1]
a.append(0) # 在a的最后面追加一个0
print(a)
# [1, 2, 3, 4, 1, 1, -1, 0]
在指定的地方添加项:

a = [1,2,3,4,1,1,-1]
a.insert(1,0) # 在位置1处添加0
print(a)
# [1, 0, 2, 3, 4, 1, 1, -1]

删除元素
a = [1,2,3,4,1,1,-1]
a.remove(2) # 删除列表中第一个出现的值为2的项
print(a)
# [1, 3, 4, 1, 1, -1]

用del删
li = [1, 2, 3, 4]
del li[3]
print(li)
# Output [1, 2, 3]

pop删索引出
li = [1, 2, 3, 4]
li.pop(2)
print(li)
# Output [1, 2, 4]

显示特定位:

a = [1,2,3,4,1,1,-1]
print(a[0]) # 显示列表a的第0位的值
# 1

print(a[-1]) # 显示列表a的最末位的值
# -1

print(a[0:3]) # 显示列表a的从第0位 到 第2位(第3位之前) 的所有项的值 切片
# [1, 2, 3]

print(a[5:]) # 显示列表a的第5位及以后的所有项的值
# [1, -1]

print(a[-3:]) # 显示列表a的倒数第3位及以后的所有项的值
# [1, 1, -1]

li = [1, 2, 3, 4]
li = li[:2] + li[3:]
print(li)
# Output [1, 2, 4]

打印列表中的某个值的索引(index):

a = [1,2,3,4,1,1,-1]
print(a.index(2)) # 显示列表a中第一次出现的值为2的项的索引
# 1
统计列表中某值出现的次数:, 而len()是list总长度

a = [4,1,2,3,4,1,1,-1]
print(a.count(-1))
# 1

对列表的项排序:

a = [4,1,2,3,4,1,1,-1]
a.sort() # 默认从小到大排序
print(a)
# [-1, 1, 1, 1, 2, 3, 4, 4]

a.sort(reverse=True) # 从大到小排序
print(a)
# [4, 4, 3, 2, 1, 1, 1, -1]
多维列表 二维数组咯

创建二维列表
一个一维的 List 是线性的 List,多维 List 是一个平面的 List:

1
2
3
4
5
6
7
8
9
10
11
12
a = [1,2,3,4,5] # 一行五列

multi_dim_a = [[1,2,3],
[2,3,4],
[3,4,5]] # 三行三列


print(a[1])
# 2

print(multi_dim_a[0][1])
# 2

list() 函数

拉链 zip

zip 函数接受任意多个(包括 0 个和 1 个)序列作为参数,合并后返回一个 tuple 的列表,请看示例:

1
2
3
4
5
6
7
a=[1,2,3]
b=[4,5,6]
ab=zip(a,b)
print(list(ab)) #需要加list来可视化这个功能
"""
[(1, 4), (2, 5), (3, 6)]
"""

字典, dict

对象?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a_list = [1,2,3,4,5,6,7,8]

d1 = {'apple':1, 'pear':2, 'orange':3}
d2 = {1:'a', 2:'b', 3:'c'}
d3 = {1:'a', 'b':2, 'c':3}

print(d1['apple']) # 1
print(a_list[0]) # 1

del d1['pear'] # 和js的delete不同, js删数组的会保留位置, 只是设undefined而已
print(d1) # {'orange': 3, 'apple': 1}

d1['b'] = 20
print(d1) # {'orange': 3, 'b': 20, 'pear': 2, 'apple': 1}

模块安装

1
2
3
4
5
6
7
8
9
10
11
先安装
pip install numpy # 这是 python2+ 版本的用法
pip3 install numpy # 这是 python3+ 版本的用法

或更新
pip install -U numpy # 这是 python2+ 版本的用法
pip3 install -U numpy # 这是 python3+ 版本的用法

再使用
import numpy as np
import matplotlib.pyplot as plt

这里的 Numpy 和 matplotlib 都是外部模块, 需要安装以后才会有的. 他不属于 python 自带的模块.

import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time
print(time.localtime()) #这样就可以print 当地时间了
""""
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=14, tm_min=12, tm_sec=48, tm_wday=4, tm_yday=358, tm_isdst=0)
""""

import time as t # 重命名
print(t.localtime()) # 需要加t.前缀来引出功能

from time import time, localtime # 只import自己想要的功能.
print(localtime())
print(time())

from time import * # 所有模块

没有导出这, 直接就用

读写文件

写, 只读,写, 添加

1
2
3
4
5
6
my_file=open('my file.txt','w')   #用法: open('文件名','形式'), 其中形式有'w':write;'r':read.
my_file=open('my file.txt','a') # 'a'=append 以增加内容的形式打开


my_file.write(text) #该语句会写入先前定义好的 text
my_file.close() #关闭文件

读, 所有文件, 按行读文件

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
一下读所有内容
file= open('my file.txt','r')
content=file.read()
print(content)


使用一次readline读一行

file= open('my file.txt','r')
content=file.readline() # 读取第一行
print(content)

"""
This is my first test.
"""

second_read_time=file.readline() # 读取第二行
print(second_read_time)

"""
This is the second line.
"""

读所有行到 list []
file= open('my file.txt','r')
content=file.readlines() # python_list 形式
print(content)

"""
['This is my first test.\n', 'This is the second line.\n', 'This the third line.\n', 'This is appended file.']
"""

# 之后如果使用 for 来迭代输出:
for item in content:
print(item)

"""
This is my first test.

This is the second line.

This the third line.

This is appended file.
"""

input

1
2
3
4
5
6
7
a_input=input('please input a number:')
print('this number is:',a_input)

''''
please input a number:12 #12 是我在硬盘中输入的数字
this number is: 12
''''

input 在判断中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a_input=int(input('please input a number:'))#注意这里要定义一个整数型
if a_input==1:
print('This is a good one')
elif a_input==2:
print('See you next time')
else:
print('Good luck')

"""
please input a number:1 #input 1
This is a good one

please input a number:2 #input 2
See you next time

please input a number:3 #input 3 or other number
Good luck
"""

错误处理 try except else finally

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try:
file=open('eeee.txt','r') #会报错的代码
except Exception as e: # 将报错存储在 e 中
print(e)
"""
[Errno 2] No such file or directory: 'eeee.txt'
"""

def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("result is", result)
finally:
print("executing finally clause")

id 看地址, copy, deepcopy

什么是 id?一个对象的 id 值在 CPython 解释器里就代表它在内存中的地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> import copy
>>> a=[1,2,3]
>>> b=a
>>> id(a)
"""
4382960392
"""
>>> id(b)
"""
4382960392
"""
>>> id(a)==id(b) #附值后,两者的id相同,为true。
True
>>> b[0]=222222 #此时,改变b的第一个值,也会导致a值改变。
>>> print(a,b)
[222222, 2, 3] [222222, 2, 3] #a,b值同时改变

当使用浅拷贝时,python 只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。看代码:

1
2
3
4
5
6
7
8
9
10
>>> import copy
>>> a=[1,2,3]
>>> c=copy.copy(a) #拷贝了a的外围对象本身,
>>> id(c)
4383658568
>>> print(id(a)==id(c)) #id 改变 为false
False
>>> c[1]=22222 #此时,我去改变c的第二个值时,a不会被改变。
>>> print(a,c)
[1, 2, 3] [1, 22222, 3] #a值不变,c的第二个值变了,这就是copy和‘==’的不同

deepcopy 对外围和内部元素都进行了拷贝对象本身,而不是对象的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#copy.copy()

>>> a=[1,2,[3,4]] #第三个值为列表[3,4],即内部元素
>>> d=copy.copy(a) #浅拷贝a中的[3,4]内部元素的引用,非内部元素对象的本身
>>> id(a)==id(d)
False
>>> id(a[2])==id(d[2])
True
>>> a[2][0]=3333 #改变a中内部原属列表中的第一个值
>>> d #这时d中的列表元素也会被改变
[1, 2, [3333, 4]]


#copy.deepcopy()

>>> e=copy.deepcopy(a) #e为深拷贝了a
>>> a[2][0]=333 #改变a中内部元素列表第一个的值
>>> e
[1, 2, [3333, 4]] #因为时深拷贝,这时e中内部元素[]列表的值不会因为a中的值改变而改变
>>>

总结

看成 2 块: 基本数据类型和序列, 函数, 面向对象, 循环和判断, 运算,

基本数据类型

  1. 变量不需要声明,不需要删除,可以直接回收适用。注意声明多个函数 a,b=1,2 和声明为 tuple a=1,2 当然可以在函数中 return 一个 tuple
  2. type(): 查询数据类型
  3. 有 None, int, float, bool, string. function, tuple, list, dict. 类 class 是 type. 都是对象, 就算是 a=1 也是引用, 不过是不可变数据对象, 可以当做 c 的值处理.

序列

  1. tuple 元素不可变,list 元素可变
  2. 字符串是一种 tuple
  3. 序列的引用 s[2], s[1:8:2]

运算

  1. 判断 ==, !=, >, >=, <, <=, in
  2. 数学 +, -, *, /, **, %
  3. 逻辑 and, or, not
  4. 类上的算特殊方法,当然有[:]

缩进

  1. :冒号
  2. 4 个空格

循环

  1. range(start, stop, step), [)
  2. for 元素 in 序列:
  3. while 条件:
  4. continue
  5. break
  6. 利用 enumerate()函数,可以在每次循环中同时得到下标和元素:返回的是一个包含两个元素的定值表(tuple)
  7. zip, 如果你多个等长的序列,然后想要每次循环时从各个序列分别取出一个元素, 合并成一个 tuple,可以利用 zip()方便地实现, 聚合列表

函数, 函数也是对象哦

  1. 定义和 return
  2. 默认参数, 自调用, 关键参数(传递是根据每个参数的名字传递参数, 可以和常见的位置传参混用), 可变参数(包裹传递加 tuple, 包裹关键字传递\* dict. 定义的时候使用是 packeging, 函数调用的时候用和\*就是 unpackaging).
  3. lambda,
  4. map()的功能是将函数对象依次作用于表的每一个元素. map()的返回值是一个循环对象。可以利用list()函数,将该循环对象转换成表。
  5. filter(func,[10,56,101,500]) 通过读入的函数来筛选数据, filter 返回的不是表,而是循环对象。 reduce()函数

循环对象: 相对于序列,用循环对象的好处在于:不用在循环还没有开始的时候,就生成好要使用的元素。所使用的元素可以在循环过程中逐次生成。这样,节省了空间,提高了效率,编程更灵活

  1. 有一个__next__()方法, 这个方法的目的是进行到下一个结果,而在结束一系列结果之后,举出StopIteration错误
  2. 迭代器: 从技术上来说,循环对象和 for 循环调用之间还有一个中间层,就是要将循环对象转换成迭代器(iterator)。这一转换是通过使用iter()函数实现的。但从逻辑层面上,常常可以忽略这一层,所以循环对象和迭代器常常相互指代对方。
  3. 生成器(generator)的主要目的是构成一个用户自定义的循环对象。 生成器表达式(Generator Expression) G = (x for x in range(4))
  4. 表推导(list comprehension)是快速生成表的方法. L = [x**2 for x in range(10)]

面向对象

将东西根据属性归类 ( 将 object 归为 class )
方法是一种属性,表示动作
用继承来说明父类-子类关系。子类自动具有父类的所有属性。
self 代表了根据类定义而创建的对象。这个参数表示某个对象。对象拥有类的所有性质,那么我们可以通过 self,调用类属性。

建立对一个对象: 对象名 = 类名()
引用对象的属性: object.attribute

通过 self 调用类属性
__init__(): 在建立对象时自动执行
类属性和对象的性质的区别

反过头来看看

  1. len() dir() help()
  2. 数据结构 list(列表)是一个类。
  3. 运算符是方法

字典也叫容器

  1. 类似对象但 key 可以是数字或布尔, map?
  2. 没有序列, 没有下标, 用 key

词典的每个元素是键值对。元素没有顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dic = {'tom':11, 'sam':57,'lily':100}

dic['tom'] = 99 # 加一个元素

for key in dic: ...

del, len()

>>>print dic.keys() # 返回dic所有的键

>>>print dic.values() # 返回dic所有的值

>>>print dic.items() # 返回dic所有的元素(键值对), 不是js的entries()

>>>dic.clear() # 清空dic,dict变为{}

文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f = open(name, "r") # f = open(文件名,模式) 创建文件对象

文件对象的方法
读取:
content = f.read(N) # 读取N bytes的数据, 不填表示所有都读入
content = f.readline() # 读取一行
content = f.readlines() # 读取所有行,储存在列表[]中,每个元素是一行。

写入:

f.write('I like apple') # 将'I like apple'写入文件

关闭文件:

f.close()

模块

  1. 通过模块.对象的方式来调用引入模块中的某个对象, (被引用的那个没有导出关键字, 就是普通的一个 py 文件)
    1. 4 种 import
  2. Python 会在以下路径中搜索它想要寻找的模块:
    1. 标准库的安装路径
    2. 程序所在的文件夹
    3. 操作系统环境变量 PYTHONPATH 所包含的路径
  3. 模块包
    1. import this_dir.module 引入 this_dir 文件夹中的 module 模块(文件)。
    2. 该文件夹中必须包含一个init.py 的文件,提醒 Python,该文件夹为一个模块包。__init__.py可以是一个空文件。

特殊方法, python 中一切都是对象, 对象就有方法

  1. dir() 来查看
  2. 运算符是通过调用对象的特殊方法实现的
  3. 对于内置的对象来说(比如整数、表、字符串等),它们所需要的特殊方法都已经在Python中准备好了。而用户自己定义的对象也可以通过增加特殊方法,来实现自定义的语法。特殊方法比较靠近Python的底层,许多Python功能的实现都要依赖于特殊方法。我们将在以后看到更多的例子。

参考

mac 下安装 Python3.*(最新版本)
莫烦 python
Python 快速教程

hexo中使用LaTex公式的开启方法

发表于 2018-11-25 | 分类于 前端教程

hexo中使用LaTex公式的开启方法

如果你的hexo 主题就是next的那么就不需要下面的3, 4步(因为hexo有mathjax的配置), 只需要1, 2, 5, 6, 7, 8
第2步和第8步是注意点

第一步: 安装Kramed

更换hexo的markdown渲染引擎为hexo-renderer-kramed, 用来支持mathjax公式输出

1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

在hexo的package.json中显示如下

1

第二步: 更改kramed文件配置(重点, 不然实现不了行间)

打开文件/node_modules/hexo-renderer-kramed/lib/renderer.js, 作如下更改:

1
2
3
4
5
6
7
// Change inline math rule
function formatText(text) {
// Fit kramed's rule: $$ + \1 + $$
// return text.replace(/`\$(.*?)\$`/g, '$$$$$1$$$$');
// 第67行直接返回text
return text;
}

2.png

第三步: 停止使用hexo-math 并安装mathjax包

虽然在package.json中看不到hexo-math , 但还是要卸载

1
2
npm uninstall hexo-math --save
npm install hexo-renderer-mathjax --save

3.png

第四步: 更新 Mathjax 的 配置文件

打开/node_modules/hexo-renderer-mathjax/mathjax.html
如图所示更改<script>为:只是改域名, 后面的config别变

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js"></script>

最新的mathjax的cdn地址去这里搜索

4.png

第五步: 更改默认转义规则

因为LaTeX与markdown语法有语义冲突,所以 hexo 默认的转义规则会将一些字符进行转义,所以我们需要对默认的规则进行修改.
打开/node_modules\kramed\lib\rules\inline.js

改两个rule

1
2
escape: /^\\([`*\[\]()#$+\-.!_>])/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

5.png

第六步: 开启mathjax

打开/themes/next主题目录下的_config.yml文件
不同的主题不同的配置文件不同, 找你安装的主题是啥

我们需要在_config.yml文件 中开启 Mathjax,(不同的主题配置方法略微有区别)

6.png

第七步: 在new 一个文章的时候加上mathjax: true

7.png

第八步: 重新生成 hexo clean+ hexo g

latex常用语法

发表于 2018-11-24 | 分类于 前端教程

latex常用语法

latex是用来排版文章和数学公式的.基于Tex. 类似web, html+css => 网页.
这是有.tex+.cls/sty => pdf, 也是内容和样式分离.

中科大Latex模板 里面还有一个106分钟的教程
清华大学Latex模板

在线latex公式

基本使用

首先不需要自己安装, 用在线的好了YouTube视频他推荐的shareLatex, 现在会跳转到overleaf

vscode上装了Latex的这个LW, 但是不能预览, 不晓得怎么回事.

也不需要懂各种文件的格式, 只需要先会用好了. 懂一点语法.能预览看.

跟着视频走一遍

基本上懂了

基本知识

  1. LATEX中的公式概念

当做命令吧: 以\开头, 必选参数{} 可选参数[]

  1. 环境的概念

以\begin{环境名}开始, \end{环境名}结束

  1. LATEX中排版文字和公式: 所有有书序模式和文本模式

注意: 如果hexo出现不能显示公式的问题.

  1. 那么可以用在线的latex中转图片来代替, 虽然这种方式不好,比如遇到f(x)
  2. 开启hexo的MathJax功能(推荐): 这样就可以用$来写公式.
hexo中使用LaTex公式的开启方法(适用于next主题和非next主题)

其他参考:
1. hexo的next主题开启mathjax
2. 使用LaTex添加公式到Hexo博客里

数学公式基本语法 不会没关系,用在线latex公式

常见的一些

命令 效果 命令 效果
\sqrt{2} $\sqrt{2}$ \sqrt[3]{2} $\sqrt[3]{2}$
x_2 $x_2$ x^2 $x^2$
\frac{1}{2} $\frac{1}{2}$ \lim_{x\to2}x^2+2 $\lim_{x\to2}x^2+2$

$\lim\limits_{\substack{\sigma\rightarrow0 \
\tau_0\rightarrow0}}\frac{\sigma}{\tau_0} $

命令 效果 命令 效果
\sum $\sum$ \sum_{i=1}^{n} $\sum_{i=1}^{n}$
\int $\int$ \int_{a}^{b} $\int_{a}^{b}$
\iint $\iint$ \iint_{a}^{b} $\iint_{a}^{b}$
\prod $\prod$ \prod_{i=1}^{n} $\prod_{i=1}^{n}$
\bigcup $\bigcup$ \bigcup_{i=1}^{n} $\bigcup_{i=1}^{n}$
\bigcap $\bigcap$ \bigcap_{i=1}^{n} $\bigcap_{i=1}^{n}$

一些希腊字母

命令 效果 命令 效果
\alpha $\alpha$ \beta $\beta$
\gamma $\gamma$ \delta $\delta$
\epsilon $\epsilon$ \zeta $\zeta$
\eta $\eta$ \theta $\theta$
\iota $\iota$ \omega $\omega$
\lambda $\lambda$ \mu $\mu$
\xi $\xi$ \phi $\phi$
\pi $\pi$ \rho $\rho$
\sigma $\sigma$ \tau $\tau$
\upsilon $\upsilon$ \nu $\nu$
\chi $\chi$ \psi $\psi$
\kappa $\kappa$

如果使用大写的希腊字母,把命令的首字母变成大写即可,例如 \Gamma 输出的是 $\Gamma$。

如果使用斜体大写希腊字母,再在大写希腊字母的LaTeX命令前加上var,例如\varGamma 生成 $\varGamma$。

MathJax basic tutorial

宏包 \package{packageName}

就是引入模块

latex常见文件类型

LaTex模板常见文件类型 功能介绍
.dtx Documented LaTeX sources,宏包重要部分
.ins installation,控制 TeX 从 .dtx 文件里释放宏包文件
.cfg config, 配置文件,可由上面两个文件生成
.sty style files使用\usepackage{...}命令进行加载
.cls classes files,类文件,使用\documentclass{...}命令进行加载
.aux auxiliary, 辅助文件,不影响正常使用
.bst BibTeX style file,用来控制参考文献样式

参考

脚丫先生的LaTeX入门

保存的代码

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
\documentclass{article}   {report}
\usepackage[utf8]{inputenc}

\title{Hello Workld}
\author{pppxehng}
\date{Augest 2018}

\begin{ducument}

\maketitle

\section{Introduction}

HELLO Workld

\end{document}


然后学习
chapters section paragraph sub-section

\documentclass{report}
\usepackage[utf8]{inputenc}
\usepackage{geometry}
\geometry{
a4paper,
total = {160mm,245mm},
left = 30mm,
top = 30mm
}

\begin{ducument}

\chapter{Introduction to LATEX}
\section{Introduction}

HELLO Workld
\chapter{Advantages of LATEX}

\section{section1} 这是1.1

\subsection{subsection} 默认有序1.1.1, 然后加了*号\subsection*{subsection} 就没了1.1.1

\subsubsection{{seusebsectiob }}

\paragraph{{this line}}

\end{document}

table figures images

\usepackage{graphicx}

the fig. \ref{fig: logo} is the logp
\begin{figure}[ht]
\centering
\includegraphics[width=5in]{jkk.png}
\caption{oafd logo}
\label{fig: logo} 1.1
\end{figure}


mutiple images stacks in
\usepackage{caption}
\usepackage{subcaption}


The Fig.\ref{mul_images} id an example of two images stacked side by side

\begin{figure}[ht] //h: here, t: top, b: bottom, p: page
\centering
\begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=0.4\linewidth]{ninjas.png}
\caption{figure 1}
\label{fig:first}
\end{subfigure}
\begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=0.4\linewidth]{ninjas.png}
\caption{figure 2}
\label{fig:second}
\end{subfigure}
\caption{oafd logo}
\label{mul_images}
\end{figure}


tables in LATEX
\chapter{Tables}
\begin{table}[ht]
\centering
\scalebox{2}{
\begin{tabular}{|l|c|r|}
\hline
Sr. No. & Column1 & Column 2 \\
\hline
\hline
1 & Row1Col1 & Row1Col2 \\
\hline
2 & Row2Col1 & Row2Col2 \\
\hline
3 & Row3Col1 & Row3Col2 \\
\hline
\end{tabular}
}
\caption{First Table}
\label{tab: firstTable}
\end{table}

multicolumn & multirow Tables

The Table\ref{multicolumn_table} displays a table with multicolumn header

\begin{table}[ht]
\centering
\scalebox{1.5}{
\begin{tabular}{|c|c|c|c|}
\hline
Sr & \multicolumn{3}{c|}{Multicolumn Header}\\
\cline{2-4}
No. & DataHeader1 & DataHeader2 & DataHeader3\\
\hline
1 & data1 & data2 & data3\\
\hline
2 & data1 & data2 & data3\\
\hline
3 & data1 & data2 & data3\\
\hline
4 & data1 & data2 & data3\\
\hline
\end{tabular}
}
\caption{Multicolumn Table}
\label{multicolumn_table}
\end{table}

The Table\ref{multicolumn_table} displays a table with a cell spanning multiple rows
\usepackage{multirow}

\begin{table}[ht]
\centering
\scalebox{1.5}{
\begin{tabular}{|c|c|c|}
\hline
Sr No. & Header1 & Header2\\
\hline
\multirows{2}{*}{1} & data1 & data2 \\
&data3 &data4\\
\hline
2 & data1 & data2\\
\hline
\end{tabular}
}
\caption{Multicolumn Table}
\label{multicolumn_table}
\end{table}

Equations

\usepackage{amsmath}

\chapter{Equations}

The Eqn. \ref{circleeqn} displays the equation for the circle

\begin{equation}
x^2=y^2=r2
\label{circleeqn}
\end{equation}

The equation below shows us the equatin for the circle

\begin{equation*}
x^2=y^2=r2
\label{circleeqn}
\end{equation*}

THe equation for the circle is given as $x^2=y^2=r2$



Matrices & Derivatives

Ten matrices ate show in wquatin \ref{matrix}

\begin{equation}
Y = \begin{bmatrix}
a_{11} & a_{12} & a_{13}\\
a_{21} & a_{22} & a_{23}\\
a_{31} & a_{32} & a_{33}\\
\end{bmatrix}
\begin{bmatrix}
x_1\\
x_2\\
x_3\\
\end{bmatrix}
\label{matrix}
\end{equation}

The derivative is shown in equatin \ref{derivative}

\begin{equation}
\frac{dy}{dx} = 2t^2
\label{derivative}
\end{equation}

The partial derivatives are shown in eqn \ref{partialder}

\begin{equation}
\frac{du}{dt} = 2x\frac{\partial u}{\partial x} +
2y\frac{\partial u}{\partial y}
\label{partialder}
\end{equation}


Limits, summation & Integrals


Limits are inserted in Eqn. \ref{limits}

\begin{equation}
\lim_{x\to2}x^2+2
\label{limits}
\end{equation}

Summations can be inserted as shown in eqn. \ref{sum}

\begin{equation}
\sum_{x=1}^{n}x^2=1
\label{sum}
\end{equation}

Product sequence can be inserted as shown in Eqn. \ref{prod}

\begin{equation}
\prod_{x=1}^{n}x^2
\label{prod}
\end{equation}

Eqn. \ref{int} shows integration

\begin{equatin}
\int_{0}^{n}x^2dx
\label{int}
\end{equatin}


Citations & Bibliography

直接在google scholar中搜 然后有个cite 点击Bib Tex, 然后复制在一个单独的文件中可以 qian1990new这个是cite

@article{qian1990new,
title={A new scientific field--open complex giant systems and the methodology},
author={Qian, Xuesen and Yu, Jingyuan and Dai, Ruwei},
journal={Chinese Journal of Nature},
volume={13},
number={1},
pages={3--10},
year={1990}
}

使用的使用

Thereference for this report are \cite{qian1990new} and ...

\bibliographystyle{ieeetr}
\bibliography{citation}

hexo基本使用

发表于 2018-11-23 | 分类于 前端教程

hexo基本使用

Hexo博客搭建之引用站内文章

在写文章的过程中,有时候需要引用站内的其他文章。可以通过内置的标签插件的语法post_link来实现引用。

1
{% post_link 文章文件名(不要后缀) 文章标题(可选) %}

举例 引用 Hello.md

1
{% post_link Hello %}

或者

1
{% post_link Hello 你好 %}

markdown在vscode上的简单优化

发表于 2018-11-23 | 分类于 前端教程

markdown在vscode上的简单优化

本文章只是简单介绍下在vscode上简单配置一些插件就可以体验更好的markdown

分4部分:

  1. 用Markdown All in One 来设置快捷键
  2. 用Markdown Preview Enhanced 来加强cmd+k, v的预览
  3. 用 markdownlint 来formatting 一致性,
  4. 文章markdown常用语法
  5. markdown主题
  6. 进阶使用论文latex咯

markdown All in One

Keyboard Shortcuts

Key Command
Ctrl + B Toggle bold
Ctrl + I Toggle italic
Alt + S Toggle strikethrough
Alt + C Check/Uncheck task list item
Ctl + Shift + ] Toggle heading (uplevel)
Ctl + Shift + [ Toggle heading (downlevel)
Ctl + M Toggle math environment

Available Commands cmd+shift+p

  • Markdown: Create Table of Contents 只用创建TOC
  • Markdown: Update Table of Contents

Use <!-- omit in toc --> to ignore specific heading in TOC

注意点:
list的一定要写全了才能打上x, 如- [ ] 写好了 空格别忘了
数学公式用别的LATEX 在线latex公式

Markdown Preview Enhanced

这个不仅可以用来当做预览的, 也可以有强大的快捷键

Markdown 基本要素

不过快捷键暂时用不到,只是当做预览pdf用.

markdownlint

用绿色的波浪线指出有格式错误, 按cmd+. 看详情.
可以也设置一些rules不生效

latex

如果无法在hexo中使用$来写公式, 参看这个使用LaTex添加公式到Hexo博客里

YouTube视频

文章latex常用语法

统一代码风格editorconfig

发表于 2018-11-23 | 分类于 前端教程

统一代码风格editorconfig

当多人共同开发一个项目的时候(尤其是开源的项目),可能不同的人使用者不同的编辑器. 又或者一个人在开发不同的项目中又要遵循不同项目的规范(代码风格), 当然还有即使是同一个文件,在html和css中也存在不同的代码风格问题, 麻烦就出现了.

当然可以用ESlint这个来对代码提交前进行一次检查, 我们常用的yarn prettier和yarn tslint 也算是一个优化代码风格,一个检查.

这里当然重点说的就是editorconfig来配置好, 从根本上解决问题. 其他的都是提交前的保险.

先给个常见的配置

1
2
3
4
5
6
7
8
9
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

使用editorconfig

只需要2步:

  1. 在项目根目录中创建一个.editorconfig的文件, 里面配置该项目的各种代码规范. 后面简单介绍如何配置.
  2. 安装和你使用的编辑器对应的editorconfig插件(editorconfig的默认优先级要高于编辑器的, vscode暂时不是原生就存在,要安装插件EditorConfig for Visual Studio Code)

editorconfig配置

EditorConfig 支持的常用的编码规范,如下

  • charset:文件编码。一般选utf-8
  • indent_style: 缩进类型。space和tab选一个
  • indent_size: 缩进数量。一般选4
  • insert_final_newline:是否在文件的最后插入一个空行。一般插入true
  • end_of_line:换行符格式。说明见Wiki:换行。可选值, 一般选lf
  • trim_trailing_whitespace:是否删除行尾的空格。可选值, 一般选true

配置完整说明

基本这点配置就行了, 配合prettier和ESlint一起用

一点简单的配置

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
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

# Python - https://www.python.org/
[*.py]
indent_style = space
indent_size = 4

# Shell script (bash) - https://www.gnu.org/software/bash/manual/bash.html
[*.sh]
indent_style = space
indent_size = 4

# .md 的文件
[*.md]
trim_trailing_whitespace = false

官网的一个配置例子

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
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

# Tab indentation (no size specified)
[Makefile]
indent_style = tab

# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

这里是其他一些大的项目中中editorconfig

官网

使用Promise

发表于 2018-11-21 | 分类于 javascript教程

Promise 是什么,使用 Promise

先看 async 和 await 吧,然后混入 promise

从Promise对象的方法和原型的方法上的返回和传入参数看

Promise 是什么, 主要介绍 Promise 构造函数

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。

具体描述看下面

下面主要内容是 Promise 构造函数, 构造函数主要是用来包装还未支持 promise 的函数
所以要 new 一个

1
2
3
4
5
6
7
8
9
10
11
12
13
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});

promise1.then(function(value) {
console.log(value);
// expected output: "foo"
});

console.log(promise1);
// expected output: [object Promise]

创建 Promise

Promise对象是由关键字 new 及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数——resolve 和 reject ——作为其参数。当异步任务顺利完成且返回结果值时(异步操作在executor内),会调用 resolve 函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject 函数。

高阶函数, 可以把函数作为参数或者返回函数 javascript-高阶函数

语法

1
new Promise( function(resolve, reject) {...} /* executor */  );

参数就是一个 function(resolve, reject) {...} 这个executor

!注意, 这个 executor 不是用 return, 而是返回并执行 resolve, reject 回调函数
!注意, 这个 executor 不是用 return, 而是返回并执行 resolve, reject 回调函数
!注意, 这个 executor 不是用 return, 而是返回并执行 resolve, reject 回调函数

executor是带有 resolve 和 reject 两个参数的函数 。这两个参数也是函数. (回调函数哦)

Promise构造函数执行时立即调用 executor 函数( executor 函数在 Promise 构造函数返回新建对象前被调用), resolve 和 reject 两个函数作为参数传递给 executor。executor 内部通常会执行一些异步操作,
一旦完成,可以调用 resolve 函数来将 promise 状态改成 fulfilled,或者在发生错误时调用reject函数将它的状态改为 rejected。 从这里知道, Promise 的状态是通过回调函数resolve和reject改的

即:resolve 和 reject 函数被调用时,分别将 promise 的状态改为 fulfilled(完成)或 rejected(失败)。

如果在 executor 函数中抛出一个错误,那么该 promise 状态为 rejected 。 executor 函数的返回值被忽略。

resolve 函数的作用是,将 Promise 对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject 函数的作用是,将 Promise 对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected), 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

描述

Promise 对象是一个代理对象(代理一个值),被代理的值在 Promise 对象创建时可能是未知的(比如可以是一个异步的操作,也可以直接是一个确定的值, 总之都用 Promise 包起来)。

它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的 promise 对象

一个 Promise 有以下 3 种状态: Promise 的状态是通过回调函数resolve和reject改的

  • pending: 初始状态,既不是成功,也不是失败状态。
  • fulfilled: 意味着操作成功完成。对应从调用resolve函数
  • rejected: 意味着操作失败。 对应从调用reject函数

注意: 如果一个 promise 对象处在 fulfilled 或 rejected 状态而不是 pending 状态,那么它也可以被称为settled状态。

pending 状态的 Promise 对象可能触发 fulfilled 状态并传递一个值给相应的状态处理方法 resolve ,也可能触发失败状态(rejected)并传递失败信息给 reject方法 。

从这里看出, 先是执行第一个Promise对象,然后触发回调的方法resolve reject, 产生一个新的Promise对象.
然后 👇 下面是Promise对象原型上的方法来处理(就会被触发调用),用到then catch

当其中任一种情况出现时,Promise 对象的 then 方法(这个方法是在 Promise 的原型上的, 并返回一个 Promise 对象)绑定的处理方法(handlers )就会被调用
( then 方法包含两个参数,也都是函数:onfulfilled 和 onrejected,它们都是 Function 类型。当 Promise 状态为 fulfilled 时,调用 then 的 onfulfilled 方法,当 Promise 状态为 rejected 时,调用 then 的 onrejected 方法, 所以在异步操作的完成和绑定处理方法之间不存在竞争)。

这里搞懂, 第一个Promise通过执行executor的回调函数resolve reject变为相应的fulfilled或rejected状态, 返回一个新的Promise对象.
然后then方法根据返回的新的Promise对象的状态, 调用相应的onfulfilled或onrejected方法.

所以状态是 3 种, Promise 的回调函数 2 种, then 方法的回调也是 2 种

pending fulfilled rejected
resolve reject
onfulfilled onrejected

平时见到的 then和 catch 可以链式调用的原因是因为 Promise.prototype.then 和 Promise.prototype.catch 方法返回 promise 对象

注意: then方法是在 Promise对象的原型上prototype的, Promise对象本身就 4 个方法resolve reject all race
原型上 3 个 then catch finally

2.png

属性和方法(上面涉及了 Promise 的方法和 Promise 原型上的方法, 具体介绍下)

看完方法和原型的返回, 在回顾去看下描述就更好

属性 不常用 2 个

Promise.length length 属性,其值总是为 1 (构造器参数的数目).

Promise.prototype 表示 Promise 构造器的原型.

方法和原型

Promise的方法 4 个, 都返回Promise对象

  1. Promise.resolve(value): 返回一个状态由给定value决定的Promise对象。
    如果该value是一个Promise对象,则直接返回该Promise对象;
    如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定;(注意: 应该是Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。)
1
2
3
4
5
6
7
8
9
10
11
12
// 这是一个滴啊有then方法的对象, 所以
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};

let p1 = Promise.resolve(thenable); // 这里先包装thenable
p1.then(function(value) {
// 这里执行, 最终结果.
console.log(value); // 42
});

否则的话(该value为空,基本类型或者不带then方法的对象),返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。
通常而言,如果你不知道一个值是否是Promise对象,使用Promise.resolve(value) 来返回一个Promise对象,这样就能将该value以Promise对象形式使用。

  1. Promise.reject(reason): 返回一个状态为失败的Promise对象,并将给定的失败信息reason传递给对应的处理方法catch住.(实际上只是 then(null, ...) 的语法糖)
  2. Promise.all(iterable): 这个方法返回一个新的promise对象(成功对应返回 resolve 一个 Promise 包装的所有成功 value 的数组, 失败就返回 reject 第一个失败的那个的 reason 信息),该promise对象在iterable参数对象里(不是说是数组,而是说要具有iterable接口)所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。

    这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把 iterable 里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。

  3. Promise.race(iterable): 当iterable参数里的任意一个子promise被成功或失败后(就是看最快的那个, all相当于是看最慢的),父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。(注意: Promise.race 在第一个promise对象变为Fulfilled之后,并不会取消其他promise对象的执行。)

3.png

Promise原型, 1 个属性, 3 个方法

属性就是原型都有的romise.prototype.constructor 返回被创建的实例函数. 默认为 Promise 函数

方法就是常见的 3 个, then catch finally

  1. Promise.prototype.then(onFulfilled, onRejected): 添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve. (catch只是then的一个特例)

  2. Promise.prototype.catch(onRejected): 添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.注意这个也是返回一个 Promise, 当成then只有第 2 个参数时呗

  3. Promise.prototype.finally(onFinally): 添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)

resolved.png

关于Symbol(Symbol.toStringTag): "Promise"的知识, 看Symbol.toStringTag

总结 : 看你真的完全掌握了 promise 么?

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。

Promise编程的核心思想是如果数据就绪(settled),那么(then)做点什么。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。

1
2
3
4
5
6
7
8
9
const promise = new Promise(function(resolve, reject) {
// ... some code

if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
  1. resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为fulfilled),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
  2. reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为rejected), 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

1
2
3
4
5
6
7
8
promise.then(
function(value) {
// success
},
function(error) {
// failure
}
);

立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。

1
2
3
4
5
6
7
8
9
10
11
12
13
setTimeout(function() {
console.log('three');
}, 0);

Promise.resolve().then(function() {
console.log('two');
});

console.log('one');

// one
// two
// three

上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise. resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。

特别说明:如果需要resolve()往后传递多个参数,不能直接写resolve(a1,a2,a3),这样只能拿到第一个要传的参数,需要以数组或对象去传递

1
2
3
4
5
let obj = { a1: a1, a2: a2, a3: a3 };
resolve(obj);
//or
let arr = [a1, a2, a3];
resolve(arr);

Promise 的链还停不了诶

1
2
// 这里是返回一个pending状态的Promise
new Promise(function() {});

虽然上面可以停住, 但会导致内存泄漏,毕竟一直停住了, 不释放内存.

衍生

Understand promises before you start using async/await 这个链接里面有 callback 转 promsie的

Implementing 这里有从头自己实现一个 promise的

ajax 和 fetch

参考

Promise
使用 Promises
阮一峰 es6 Promise 对象

进阶
你真的完全掌握了 promise 么?
对 Promise 状态的理解和基本用法
从如何停掉 Promise 链说起

CSS实现水平垂直居中的第10种方式

发表于 2018-11-05 | 分类于 前端

CSS实现水平垂直居中的第10种方式

参考来源

划重点,这是一道面试必考题,很多面试官都喜欢问这个问题,我就被问过好几次了
1.png
要实现上图的效果看似很简单,实则暗藏玄机,本文总结了一下CSS实现水平垂直居中的方式大概有下面这些,本文将逐一介绍一下,我将本文整理成了一个github仓库,欢迎大家star

仅居中元素定宽高适用

  • absolute + 负margin
  • absolute + margin auto
  • absolute + calc

居中元素不定宽高

  • absolute + transform
  • lineheight
  • writing-mode
  • table
  • css-table
  • flex
  • grid

absolute + 负margin

为了实现上面的效果先来做些准备工作,假设HTML代码如下,总共两个元素,父元素和子元素

1
2
3
<div class="wp">
<div class="box size">123123</div>
</div>

wp是父元素的类名,box是子元素的类名,因为有定宽和不定宽的区别,size用来表示指定宽度,下面是所有效果都要用到的公共代码,主要是设置颜色和宽高

注意:后面不在重复这段公共代码,只会给出相应提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 公共代码 */
.wp {
border: 1px solid red;
width: 300px;
height: 300px;
}

.box {
background: green;
}

.box.size{
width: 100px;
height: 100px;
}
/* 公共代码 */

绝对定位的百分比是相对于父元素的宽高,通过这个特性可以让子元素的居中显示,但绝对定位是基于子元素的左上角,期望的效果是子元素的中心居中显示

为了修正这个问题,可以借助外边距的负值,负的外边距可以让元素向相反方向定位,通过指定子元素的外边距为子元素宽度一半的负值,就可以让子元素居中了,css代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 此处引用上面的公共代码 */
/* 此处引用上面的公共代码 */

/* 定位代码 */
.wp {
position: relative;
}
.box {
position: absolute;;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}

这是我比较常用的方式,这种方式比较好理解,兼容性也很好,缺点是需要知道子元素的宽高

absolute + margin auto

这种方式也要求居中元素的宽高必须固定,HTML代码如下

1
2
3
<div class="wp">
<div class="box size">123123</div>
</div>

这种方式通过设置各个方向的距离都是0,此时再讲margin设为auto,就可以在各个方向上居中了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 此处引用上面的公共代码 */
/* 此处引用上面的公共代码 */

/* 定位代码 */
.wp {
position: relative;
}
.box {
position: absolute;;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}

这种方法兼容性也很好,缺点是需要知道子元素的宽高

absolute + calc

这种方式也要求居中元素的宽高必须固定,所以我们为box增加size类,HTML代码如下

1
2
3
<div class="wp">
<div class="box size">123123</div>
</div>

感谢css3带来了计算属性,既然top的百分比是基于元素的左上角,那么在减去宽度的一半就好了,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
/* 此处引用上面的公共代码 */
/* 此处引用上面的公共代码 */

/* 定位代码 */
.wp {
position: relative;
}
.box {
position: absolute;;
top: calc(50% - 50px);
left: calc(50% - 50px);
}

这种方法兼容性依赖calc的兼容性,缺点是需要知道子元素的宽高

absolute + transform

还是绝对定位,但这个方法不需要子元素固定宽高,所以不再需要size类了,HTML代码如下

1
2
3
<div class="wp">
<div class="box">123123</div>
</div>

修复绝对定位的问题,还可以使用css3新增的transform,transform的translate属性也可以设置百分比,其是相对于自身的宽和高,所以可以讲translate设置为-50%,就可以做到居中了,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 此处引用上面的公共代码 */
/* 此处引用上面的公共代码 */

/* 定位代码 */
.wp {
position: relative;
}
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

这种方法兼容性依赖translate2d的兼容性

lineheight

利用行内元素居中属性也可以做到水平垂直居中,HTML代码如下

1
2
3
<div class="wp">
<div class="box">123123</div>
</div>

把box设置为行内元素,通过text-align就可以做到水平居中,但很多同学可能不知道通过通过vertical-align也可以在垂直方向做到居中,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 此处引用上面的公共代码 */
/* 此处引用上面的公共代码 */

/* 定位代码 */
.wp {
line-height: 300px;
text-align: center;
font-size: 0px;
}
.box {
font-size: 16px;
display: inline-block;
vertical-align: middle;
line-height: initial;
text-align: left; /* 修正文字 */
}

这种方法需要在子元素中将文字显示重置为想要的效果

writing-mode

很多同学一定和我一样不知道writing-mode属性,感谢@张鑫旭老师的反馈,简单来说writing-mode可以改变文字的显示方向,比如可以通过writing-mode让文字的显示变为垂直方向

1
2
<div class="div1">水平方向</div>
<div class="div2">垂直方向</div>
1
2
3
.div2 {
writing-mode: vertical-lr;
}

显示效果如下:

1
2
3
4
5
水平方向
垂
直
方
向

更神奇的是所有水平方向上的css属性,都会变为垂直方向上的属性,比如text-align,通过writing-mode和text-align就可以做到水平和垂直方向的居中了,只不过要稍微麻烦一点

1
2
3
4
5
<div class="wp">
<div class="wp-inner">
<div class="box">123123</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 此处引用上面的公共代码 */
/* 此处引用上面的公共代码 */

/* 定位代码 */
.wp {
writing-mode: vertical-lr;
text-align: center;
}
.wp-inner {
writing-mode: horizontal-tb;
display: inline-block;
text-align: center;
width: 100%;
}
.box {
display: inline-block;
margin: auto;
text-align: left;
}

这种方法实现起来和理解起来都稍微有些复杂

table

曾经table被用来做页面布局,现在没人这么做了,但table也能够实现水平垂直居中,但是会增加很多冗余代码

1
2
3
4
5
6
7
8
9
<table>
<tbody>
<tr>
<td class="wp">
<div class="box">123123</div>
</td>
</tr>
</tbody>
</table>

tabel单元格中的内容天然就是垂直居中的,只要添加一个水平居中属性就好了

1
2
3
4
5
6
.wp {
text-align: center;
}
.box {
display: inline-block;
}

这种方法就是代码太冗余,而且也不是table的正确用法

css-table

css新增的table属性,可以让我们把普通元素,变为table元素的现实效果,通过这个特性也可以实现水平垂直居中

1
2
3
<div class="wp">
<div class="box">123123</div>
</div>

下面通过css属性,可以让div显示的和table一样

1
2
3
4
5
6
7
8
.wp {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.box {
display: inline-block;
}

这种方法和table一样的原理,但却没有那么多冗余代码,兼容性也还不错

flex

flex作为现代的布局方案,颠覆了过去的经验,只需几行代码就可以优雅的做到水平垂直居中

1
2
3
<div class="wp">
<div class="box">123123</div>
</div>
1
2
3
4
5
.wp {
display: flex;
justify-content: center;
align-items: center;
}

目前在移动端已经完全可以使用flex了,PC端需要看自己业务的兼容性情况

grid

css新出的网格布局,由于兼容性不太好,一直没太关注,通过grid也可以实现水平垂直居中

1
2
3
<div class="wp">
<div class="box">123123</div>
</div>
1
2
3
4
5
6
7
.wp {
display: grid;
}
.box {
align-self: center;
justify-self: center;
}

代码量也很少,但兼容性不如flex,不推荐使用

总结

下面对比下各个方式的优缺点,肯定又双叒叕该有同学说回字的写法了,简单总结下

  • PC端有兼容性要求,宽高固定,推荐absolute + 负margin
  • PC端有兼容要求,宽高不固定,推荐css-table
  • PC端无兼容性要求,推荐flex
  • 移动端推荐使用flex

扩展

在 CSS 中对元素进行水平居中是非常简单的:如果它是一个行内inline元素, 就对它的父元素应用 text-align: center; 如果它是一个块级block元素,就对它自身应用 margin: auto。然而如果要对一个元素进行垂直居中,可能光是想想就令人头皮发麻了。

基于绝对定位

1
2
3
4
5
6
7
8
9
main {
position: absolute;
top: 50%;
left: 50%;
margin-top: -3em; /* 6/2 = 3 */
margin-left: -9em; /* 18/2 = 9 */
width: 18em;
height: 6em;
}

借助强大的 calc() 函数,这段代码还可以省掉两行声明:

1
2
3
4
5
6
7
main {
position: absolute;
top: calc(50% - 3em);
left: calc(50% - 9em);
width: 18em;
height: 6em;
}

只要换用基于百分比的 CSS 变形来对元素进行偏移,就不需要在偏移量中把元素的尺寸写死。这样我们就可以彻底解除对固定尺寸的依赖:

1
2
3
4
5
6
main {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

基于 viewport

假设我们不想使用绝对定位,仍然可以采用 translate() 技巧来把这 个元素以其自身宽高的一半为距离进行移动;但是在缺少 left 和 top 的情况下,如何把这个元素的左上角放置在容器的正中心呢?

我们的第一反应很可能是用 margin 属性的百分比值来实现,就像这样:

1
2
3
4
5
6
main {
width: 18em;
padding: 1em 1.5em;
margin: 50% auto 0;
transform: translateY(-50%);
}

原因在于 margin 的百分比值是以父元素的宽度作为解析基准的(不是高度) 。没错,即使对于 margin-top 和 margin-bottom 来说也是这样!

  • vw :1% of viewport’s width
  • vh :1% of viewport’s height
  • vmin :1% of viewport’s smaller dimension
  • vmax :1% of viewport’s larger dimension
1
2
3
4
5
6
main {
width: 18em;
padding: 1em 1.5em;
margin: 50vh auto 0;
transform: translateY(-50%);
}

可以看到,其效果堪称完美。当然,这个技巧的实用性是相当有限的,因为它只适用于在视口中居中的场景。

基于 Flexbox

我们只需写两行声明即可:

  • 先给这个待居中元素的父元素设置 display: flex (在这个例子中是 <body> 元素)
  • 再给这个元素自身设置我们再熟悉不过的 margin: auto(在这个例子中是 <main> 元素):
1
2
3
4
5
6
7
8
body {
display: flex;
min-height: 100vh;
margin: 0;
}
main {
margin: auto;
}

请注意,当我们使用 Flexbox 时,margin: auto 不仅在水平方向上将元素居中,垂直方向上也是如此。

参考

参考来源
老生常谈之CSS的垂直居中666

kde manjaro

发表于 2018-07-01 | 分类于 linux

KDE桌面环境下美化

在关于系统哦中可以看到KDE plasma的版本 我当前是5.12.5

鼠标改单击打开为双击

shubiao.jpg

桌面设置为

总数设置为4个
行数2
快捷键切换桌面

切换桌面是 桌面布局 壁纸 桌面部件 面板都是一样的

活动

不同桌面不同背景KDE5中不能用了,用活动代替好了
在 系统设置-> 桌面行为 -> 活动 里创建一个新活动。
不同活动的 桌面布局 壁纸 桌面部件可以不同,但面板是一样的

快捷键是 meta+(shift+)tab

右键配置桌面(alt+d,alt+s)

壁纸有两种布局:文件夹布局和桌面布局(我的为什么切换一下就黑屏,然后要重启才好). 还能设置壁纸类型,是图片还是幻灯片或者每日一图.缩放功能
文件夹布局的区别是会默认显示主目录下/desktop 桌面文件夹中的内容.

添加部件

在左边显示的部件中,选全局菜单拖到panel中,
应用程序菜单这3个类似用3种不同的方式打开所有程序.就是程序启动器,还能自定义显示那些类别

装global menu,但这个不太好,比如用火狐显示不了菜单,文件夹可以.

额外装一个application title 只用来看应用名字.随便按下图设置一下.
applicationTitile

关于类似dock的,可以 加个空白panel 然后添加部件(图标任务管理器不要直接把图标拖入panel,不然大小不好设置),然后把宽度调一下,上面2个箭头不动,下面2个箭头设置为图标宽度好了.(记得要去设置图标任务管理器的行数只有1行才会达到自动扩大的效果)
tubiaorenwuguanliqi.jpg
dock.jpg

系统设置中

日期和时间的24小时格式设定在右击时间设置,不在系统设置中.数字时钟设定,注意24小时的选项框多点几次效果不同(三角和正方形).
time.jpg

外观

工作空间主题这里可以设置: 默认主题, 桌面主题(这个和观感差不多吧,只是小范围,桌面图片在桌面上右键配置桌面中有,改为aex),光标样式(改为capitaine cursors)和 登录时的欢迎屏幕的图片(登录框的样式在工作空间->开机和关机中设置)
aex.jpg

颜色就是设置配色问题

图标的话设置各种仿win mac的桌面图标 挺好的(macOS icons但有些图标不全,我换了个别的mac风格macos-sierra-CT的)

字体

应用程序风格:这里设置最大最小这种按钮的样式,还能自己设置放左放右边,放多少东西.(窗口装饰中主题设置为breezemite或者yosemite,按钮左右位置换一下)

工作空间

可以设置桌面行为

窗口行为:设置工作空间, 屏幕边缘(类似鼠标移到下边是显示桌面),桌面特效,触摸屏,虚拟桌面(这个用不到了,改用活动来设置好). 锁屏的时间和快捷键.活动,meta+tab切换着用

快捷键

开机和关机中可以设置登录屏幕的样式,自动启动程序,后台服务,桌面会话也就是登陆后的程序还是原来的么(类似浏览器的那个功能)

搜索

安装软件

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
sudo pacman -S vim && vim-powerline
sudo pacman -S gcc
sudo pacman -S git
sudo pacman -S zsh && sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sudo pacman -S tmux && powerline或tmux-powerline(还是不会怎么安装)

sudo pacman -S shadownsocks-qt5
sudo pacman -S electronic-wechat
sudo pacman -S tree

sudo pacman -S terminator(字体有点问题)
sudo pacman -S visual-stuido-code-bin
sudo pacman -S go

sudo pacman -S gimp
sudo pacman -S typora
sudo pacman -S sublime-text-dev(这个就是3)
sudo pacman -S wps-office
sudo pacman -S intellij-idea-community-edition

// 搜狗拼音有点多
sudo pacman -S fcitx-im
sudo pacman -S fcitx-sogoupinyin
sudo pacman -S fcitx-configtool
//然后新建~/.xprofile
sudo vim ~/.xprofile
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS="@im=fcitx"
// 按ctrl+space可以调出

// QQ和TIM,网易云音乐
sudo pacman -S deepin-wine-tim
sudo pacman -S deepin-qq-im
sudo pacman -S netease-cloud-music

移除不必要的东西

1
2
sudo pacman -R konversation
sudo pacman -R libreoffice-fresh

manjaro上安装软件

发表于 2018-06-10 | 分类于 linux

manjaro上安装软件

设置源

见[pacman源添加及]

常用软件

安装中文输入法 (有问题)
安装搜狗拼音
sudo pacman -S fcitx-sogoupinyin
sudo pacman -S fcitx-im # 全部安装
sudo pacman -S fcitx-configtool # 图形化配置工具
之后更改 ~/.xprofile
nano ~/.xprofile
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=”@im=fcitx”
最后在命令行输入fcitx就可以使用了

chrome

在配置最后加了的话直接sudo pacman -S goole-chrome可以搜到安装

1
2
3
4
# USTC
[archlinuxcn]
SigLevel = Optional TrustedOnly
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch

kde下 下拉的用yakuake 而不是gnome的 guake

1…8910…14
Henry x

Henry x

this is description

133 日志
25 分类
135 标签
GitHub E-Mail
Links
  • weibo
© 2019 Henry x