python
之前学习过python,看书,视频等等,但是发现看的都不完整。所以这一次决定好好的来从头学习一遍。打算学好python,然后再学习go语言以及vue
python环境
python是一门解释型语言,也就是说不像c语言那样可以编译好了运行,python是边解释边执行的。所以源码可见,这个解释器就是python,我们在网上下载的python就是一个解释器。下载了并安装了python就拥有了一个python环境。
查看python版本
1
python --version
第一个函数
print()
print函数默认换行,如果不换行则需要加参数1
2print("hello",end=" ")
print("world")
代码风格
python代码的一个很明显的特点就是缩进。代码块是通过缩进来组织的,代码块使用冒号
:
来标识单行注释使用
#
1
# 单行注释
多行注释使用
""" """
1
2
3
4"""
多行
注释
"""一行代码拆分多行使用
\
1
2
3
4
5user = {"name":"snippet",\
"age":"12",\
"gender":"male"
}
print(user["age"])命名规范
类命名:
使用大驼峰的规范,即每个单词都以大写字母开头1
2class UserInfo():
name = "python"变量命名:
- 第一种:小驼峰,即第一个单词小写开头,其余字母大写开头
1
baiduUrl = "https://www.baidu.com"
- 第二种:所有字母全部小写,并用
_
连接,我比较喜欢这个1
baidu_url = "https://www.baidu.com"
- 第一种:小驼峰,即第一个单词小写开头,其余字母大写开头
变量
作用:
- 变量是一个字符串,用来保存数据的内存地址,指向内存中数据Data的位置。
- 变量所保存的内存地址可以被改变,所以变量可变
- 如果在程序中多处都要使用到这个数据,那么使用变量则可以只修改一个地方就行
赋值:
由于python是解释型语言,所以在声明变量时,不需要指定变量的类型
1
name = "xiaotianquan"
还可以一次性赋值多个
1
2name,age,like = "gou",2,"food"
print(name,age,like)
引用
直接写变量名即可
数据类型
标准数据类型:
数字
直接写数字,不加引号,加了引号作为字符串
1
age = 3
字符串 str
用引号括起来的作为字符串,可以使用单引号和双引号
这两种没有区别,因为没有变量置换(shell和perl中)这种操作,它使用的是拼接布尔 True/False
在python中,布尔值也可以作为数字使用
True = 1, False = 01
2age = 3
print(age+True)列表 list
用
[]
表示,可以存储不同类型的数据1
2data = [1,2,3,4,5,6,7,"a","b"]
print(data)切片操作
使用
:
,取出指定范围的数据,可以使用函数id()
查看取出数据的内存地址1
list[start_index:end_index:step]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21data1 = [1,2,3,4]
# 作用为复制列表,使用频率高,有效的避免对原数组数据造成破坏
data2 = data1[:]
# 内存地址不同
print(id(data1),id(data2))
# 与data[:]作用相同,-1为最后一个元素的索引
data3 = data1[0:-1]
# 指定位置,前闭后开[)
data4 = data1[0:2]
# 指定步幅
data4 = data1[::2]
# 逆序
data8 = data1[-1::-1]
# 负数索引
data5 = data1[-3:-1]其它
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# 删除指定元素
data6 = data1.remove(2)
# 从后往前取出数据(删除)
data7 = data1.pop()
# 乘
data9 = data1 * 2
# 列表生成式
data10 = [ i for i in range(1,10) ]
# 嵌套
data11 = [data,data10]
# 循环取出嵌套数据
for i in data11:
for j in i:
print(j)
# 如果嵌套的两个list元素个数一致,可以使用一层嵌套即可取出所有值
la = [1,2,3,4]
lb = ["a","b","c","d"]
lc = [la,lb]
for i,j,k,l in lc:
print(i,j,k,l)
# 查看list元素个数
len(data)
# 全部为数字时,可以取最大值,最小值
max(la)
min(la)
# 查看某个元素存在多少个
la.count(1)
元组 tuple
使用
()
,为一个不可修改列表,大部分用法与list一致1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24data = (1,2,3,4,"a","b")
# 创建一个只有一个元素的tuple,后面需要一个逗号
data = (1,)
print(type(data))
# 可以不加括号
data = 1,
print(type(data))
data = 1,2,3,4
print(type(data))
# 创建空的tuple
data = tuple()
data = ()
# 通过list创建tuple
mylist = [i for i in range(1,9)]
data = tuple(mylist)
# tuple的特殊用法,两个元素交换
a = 1
b = 2
a,b = b,a集合 set
数据有序,而且不可重复,具有取出重复的作用
通过list和tuple来生成集合
1
2
3
4a = [1,2,3,4,2,1,3]
b = set(a)
print(type(b))
print(b)通过
{}
来定义集合1
2a = {1,2,2,5,3,4}
print(type(a))集合没有索引,只能for循环取出元素
1
2
3a = {i**2 for i in range(1,10)}
for i in a:
print(i)集合运算
1
2
3
4
5
6
7
8a = {i for i in range(1,5)}
b = {i for i in range(3,7)}
# 交集
c = a.intersection(b)
# 并集
d = a.union(b)
# 差集
e = a.difference(b)让集合不可修改
1
2a = { i for i in range(1,5)}
b = frozenset(a)其它
1
2
3
4
5
6
7
8
9
10
11
12
13# 生成奇数、偶数集合
a = {i for i in range(1,10) if i % 2 == 0}
b = {i for i in range(1,10) if i % 2 != 0}
# 删除集合中的数,如果不存在则会报错
sa = {i for i in range(1,10)}
sa.remove(1)
# 删除集合中的数,如果不存在不会报错
sa.discard(11)
# 集合中也有pop函数,但是是随机的
sa.pop()
- 字典 dict
数据类型嵌套-对象
在list,tuple,set,dict中均可以存储对象
1 | class User(): |
运算符
- 算数运算符
- 关系运算符
- 赋值运算符
- 逻辑运算符
- 位运算
- 成员运算符
- 身份运算符
算数运算符
- python没有自增自减运算符
- 包括:
- 加
+
- 减
-
- 乘
*
- 除
- 普通除法
/
- 取余
%
- 取整
//
- 普通除法
- 加
- 所有运算符都可以使用运算赋值的缩写:
+=
,-=
,*=
,/=
,%=
,//=
已经有运算赋值这两个操作了,所以不能再赋值1
2
3a = 1
a += 1
print(a)
比较运算符
比较运算的结果一定为一个布尔值:True/False
- 等于
==
- 不等于
!=
1
print(3!=4)
- 其它
>
>=
<
<=
赋值运算符
使用等号来赋值=
,将数据data赋值给变量
逻辑运算符
返回结果为True/False
- and
- or
- not
1 | a = 1 |
成员运算符
用来检测一个值或者变量是否在一个集合中,返回结果为True/False
- in
- not in
1
2
3
4
5a = 1
b = [i for i in range(1,5)]
c = a in b
d = a not in b
print(c,d)
身份运算符
用来判断两个变量是否一致,返回结果为True/False
- is
- is not
1
2
3
4
5
6a = 1
b = 1
c = 2
print(a is b)
print(a is c)
print(a is not c)
程序结构
- 顺序
程序从上到下依次执行 - 循环
for
while
- 分支
if
分支结构
这里的条件表达式只要是返回结果为True/False即可
1 | if 条件表达式: |
举例1:
1 | user = input("type your name: ") |
举例2:空字符串为假
1 | if "": |
循环结构
for循环
用来遍历序列中的所有元素
1 | for 变量 in 序列: |
举例:
1 | for i in range(1,10): |
- 循环中的条件跳转
- break 终止循环
- continue 跳过continue后的语句
- pass 没有实际作用,用来占位
举例:
1 | for i in range(2,20): |
while循环
当条件成立时,一直循环。这个条件必须要有终止,否则会形成死循环。
1 | while 条件表达式: |
举例1:
求a,b的最小公约数
1 | a = 2 |
举例2:
1 | i = 1 |
函数
命名
一般采用:动词_名词
的形式意义
复用代码定义
1
2def 函数名():
语句调用
1
函数名()
举例:
1
2
3
4
5import time
def get_time():
now = time.strftime("%Y%m%d-%H:%M:%S")
print(now)
get_time()
参数
分类方式1:
形参:在写函数时,括号中的那个参数
1
2def get_name(name):
print(name)实参:在函数调用时括号中传入的参数
1
get_name("小舞")
分类方式2:
位置参数:在传参时必须一一对应
1
2
3def normal(name,age,like):
print("{} is {} years old and like {}".format(name,age,like))
normal("小舞",20,"star")关键字参数:在传参时不必一一对应,而是使用参数名来设置参数
1
2
3def keyword(name,age,like):
print("{} is {} years old and like {}".format(name,age,like))
keyword(age=20, name="小舞", like="star")默认参数: 给参数设置默认值,如果不传则使用默认值,不过默认参数后面不能写位置参数
1
2
3def default(a,b,c=1):
print((a + b) / c)
default(1,2)收集参数:在不确定会传入参数个数的情况下使用
- 如果后面还有位置参数,那么位置参数会作为关键字参数,而且位置不能变
- 如果有两个星号,那么表示收集所有参数包括关键字参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14def collection(*count):
sum = 0
for i in count:
sum += i
return sum
collection(1,2,3,4)
def collection(*count,another=1):
sum = 0
for i in count:
sum += i
return sum + another
collection(1,2,3,4,another=5)
分解参数:
将list和元组作为参数传给函数时
1
2
3
4
5
6
7
8
9def expend(*args):
sum = 0
for i in args:
sum += i
return sum
a = (i for i in range(1,10))
b = [i for i in range(1,10)]
print(expend(*a))
print(expend(*b))将字典作为参数传给函数时
1
2
3
4
5
6
7def expend(**args):
sum = 0
for i in args:
sum += args[i]
return sum
c = {"a":1,"b":2,"c":3}
expend(**c)
返回值
- 函数可以有返回值,也可以没有返回值,使用
return
来返回执行结果 - 但是在python中还是推荐有返回值,如果没有实际值返回可以返回一个
None
- 函数一旦执行return之后函数就会结束,return后面的语句不会执行
举例:
1 | def sum(a,b): |
计算九九乘法表:我写的挺复杂
1 | for y in range(1,10): |
简单写法
1 | for y in range(1,10): |
三角形
1 | for y in range(1,10): |
递归函数
函数直接或者间接调用自己,需要有结束条件
优缺点:
- 优点:书写理解简单
- 缺点:执行速度慢
写法:
结束条件
1
2
3
4
5
6
7def plus(num):
if num == 1:
return 1
# 这个函数调用时,传入1,得到plus(1) = 1
# 不能这么写,这么写是错误的
def plus(num):
plus(1) = 1返回自己
1
2
3
4
5def plus(num):
if num == 1:
return 1
return num + plus(num-1)
plus(100)举例:斐波拉契数列
普通写法
1 | # 1, 1, 2, 3, 5, 8, 13..... |
使用递归写法
1 | # 1, 1, 2, 3, 5, 8, 13..... |
尾递归
对比普通写法和递归的写法,递归函数在调用40次时已经停止调用了,而且在求同一个斐波拉契数的时候,普通写法速度秒杀递归写法。普通写法单线程求第十万个斐波拉契数不到一秒,第一百万个斐波拉契数约六秒。所以递归函数不适合复杂计算
递归函数为什么慢?因为递归函数运行时,每一次调用都会返回一个表达式
,不能返回一个确定的值,那么原函数的参数,逻辑结构等这些都不能修改,每次计算机在调用函数时会使用堆栈,每调用一个函数会增加一层栈帧,所以当递归过程多次调用函数的时候可能会导致大小有限的堆栈溢出。优化方式之一是尾递归
为什么尾递归可以优化?尾递归与递归都需要调用自身,看起来没多大区别(我刚开始也没看懂),但是尾递归每次都不是返回的表达式,而是返回的一个函数,至于计算结果,那是通过变量的形式进行传递的,这么做的好处就是不用开新的栈,而是刷新原函数,将参数传递进去就好了。所以做到了优化,但是python中即使是使用了尾递归,次数仍然只能达到999次。并不是真正意义上的尾递归
在很多时候我们都是在刷新变量的值,而并不是重新用一个别的变量
1 | sum = 0 |
尾递归的斐波拉契函数写法:
1 | # 1, 1, 2, 3, 5, 8, 13..... |
利用三目运算简写
1 | def fib(num, first=1, second=1, sum=2): |
通过上面尾递归的写法,可以看出函数调用自身的作用类似于计数,真正计算的过程在参数中。其实类似于普通函数的写法
函数的使用
在python中一切皆是对象,所以函数也是对象,函数名指向的是代码段的内存地址
作为元素使用:放在list,tuple,set,dict中
1
2
3
4def user():
print("hello")
one = user()
a = [one]作为参数传递给函数
可以被赋值
作为函数的返回值
字符串
在linux相关的运维上,有很多都是处理字符串,所以字符串有点重要的
路径问题
在很多情况下,输入路径需要各种转义才行,为了避免这种麻烦,使用r
1 | location = r'c:\user\kite\desktop' |
变量替换(字符串拼接、格式化)
%
1
print("i like %s and %s"%("cat","dog"))
format
函数,使用{}
直接使用
1
print("i like {} and {}".format("cat","dog"))
使用变量
1
2a = "i like {} and {}"
print(a.format("cat","dog"))指定位置
1
2a = "i like {0} and {0} and {1}"
print(a.format("cat","dog"))使用命名:
- 我觉得这种还不错,虽然字多了一点,但是很清晰
1
2a = "i like {animal} and {animal} and {drink}"
print(a.format(animal="cat",drink="juice")) - 在传入的参数比较多时,使用字典是最好的,需要使用到参数分解,这个是目前我觉得最好的
1
2
3a = "i like {animal} and {animal} and {drink}"
b = {"animal":"cat","drink":"juice"}
print(a.format(**b))
- 我觉得这种还不错,虽然字多了一点,但是很清晰
指定数字长度
1
2a = "pi is {:.2f}"
print(a.format(1.1314))
判断类函数
函数以is
开头,返回值为True
/False
内置函数
字符串的关键字为str
,通过str来查看帮助文档
1 | help(str) |
举例
1 | url = r"https://www.baidu.com" |
类与对象
类通过class来定义,对象由类实例化而来。类的作用在于为对象提供一个模板,它包含了属性和函数。最重要的是类提供了继承,封装,多态这三大特性。
1 | # 定义类 |
查看类的所有方法:__dict__
1 | str.__dict__ |
类属性和方法
在类定义之后,就在内存中保存了类的属性和方法,可以直接调用
1 | class User(): |
实例方法:使用最多的方法,需要将类实例化成为对象,通过对象调用方法
静态方法:
- 不需要实例化,通过类直接调用
- 静态方法包装在staticmethod类的对象中,定义中没有self,可直接通过类来调用方法
1
2
3
4
5
6class MyClass():
def tellme():
print("i am a static method,without self")
tellme = staticmethod(tellme)
MyClass.tellme()
类方法:
- 不需要实例化,通过类直接调用,如果调用需要传参的函数,则将类自己作为参数传递进去
- 类方法包装在classmethod类的对象中,参数为cls,虽然可以通过对象来调用,但是实际上cls还是会关联到类的方法
1
2
3
4
5
6class MyClass():
def tellme(cls):
print("i am a class method,with args sls")
tellme = classmethod(tellme)
MyClass.tellme()
装饰器
- 上面的类方法和静态方法,需要手动写,但是可以通过使用装饰器来自动包装
- 用来替代手工包装,可用于包装任何可调用对象,还可用于方法和函数。装饰器可以有多个,指定多个时,应用的顺序与列出的顺序相反
1
2
3
4
5class MyClass():
def tellme():
print("new decorator")
MyClass.tellme()
self
- self作为一个参数,常常用在类的函数中,但并不是所有类的函数都需要这个参数
- self并不是一个关键字,也可以用其它的替代
- 如果这个函数需要访问类的属性,那么需要self这个参数,它用来指代实例自身
- 如果这个函数不需要访问类的属性,那么不需要self这个参数
- 在有self的时候,首先会看函数自己是否定义属性,如果没有,则访问类的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class User():
age = 20
id = 1
qq = 102832343
def info():
print("hello")
def get_age(self):
return self.age
def get_qq(self):
self.qq = 2312323123
return self.qq,self.age
one = User()
one.info()
print(one.get_age())
print(one.get_qq())
继承
继承父类的属性,函数等。避免了代码的冗余,也可重写父类的方法
将父类作为参数传递给子类
子类可以继承自多个类
1
2
3
4
5
6
7
8
9
10
11
12
13class User():
name = "one"
age = 20
def get_name(self):
return self.name
class Customer():
id = 1
class Realone(User,Customer):
pass
a = Realone()
a.get_name()
print(a.id)子类扩充父类的方法:使用
super()
调用父类方法1
2
3
4
5
6
7
8
9
10
11class User():
name = "journal"
def get_name(self):
print(self.name)
class SomeOne(User):
def get_info(self):
super().get_name()
print("attend super")
a = SomeOne()
a.get_info())检测是否为子类
1
print(issubclass(Realone,User))
构造函数
在类实例化的时候第一个自动调用的函数,作用是给对象初始化一些数据
必须有参数self,函数名为
__init__
1
2
3
4
5
6class User():
def __init__(self):
self.name = "lixingyun"
a = User()
print(a.name)通过继承,扩展父类的构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class User():
def __init__(self,name):
self.name = name
print(name)
# 直接写父类的init方法,只能写一个父类,不推荐使用
class One(User):
def __init__(self,name):
# 先调用父类的init函数
User.__init__(self,name)
print("initial finish")
# 可以自动向上寻找父类的init方法,父类没有写死,推荐使用
class Two(User):
def __init__(self,name):
super(Two,self).__init__(name)
print("initial finish")
a = One("小小")
b = Two("小小")构造函数默认被继承
如果定义了自己的构造函数,那么父类的构造函数不再被继承。也叫重写父类函数
封装
封装即为对对象成员进行访问限制
私有:最高级别的限制,只能在当前类或者对象中访问。通过在变量前加
__
实现1
2
3
4
5
6class User():
__name = "喜洋洋"
__age = 20
one = User()
# 无法直接访问
print(one.name)其实私有也不是真的无法访问,还是可以访问的
1
print(one._User__age)
受保护的:在外部不可访问,可以在内部和子类中访问。通过在变量前加
_
实现公有的:任何地方都可以使用
多态
- 同一个对象在不同情况下有不同的状态
- 在python中是一种设计思想,并没有语法要求,其实我也搞不懂
类的函数转属性
类中的get,set,del函数可以转换为属性
1 | class User(): |
可以使用property(get,set,del)
函数对get,set,del封装。将函数转换为一个属性值
1 | class User(): |
类的内置属性
__dict__
: 显示类的属性和方法__doc__
: 类的说明文档__name__
: 类的名称__bases__
: 类的所有父类
类的魔法函数
不需要手动调用,达到触发条件,自动调用
__init__
: 初始化类的属性__call__
: 当对象被当做函数使用的时候,调用此函数1
2
3
4
5class User():
def __call__(self):
print("此时对象被当做函数调用了")
one = User()
one()__str__
: 当对象被当做字符串使用的时候,调用此函数1
2
3
4
5class User():
def __str__(self):
return "此时对象被当做字符串使用了"
one = User()
print(one)__getattr__
: 当访问一个不存在的属性时,调用此函数1
2
3
4
5
6class User():
def __getattr__(self,method):
return "此函数不存在"
one = User()
print(one.age)
抽象
- 抽象方法
定义了方法,但没有实现
1 | class User(): |
抽象类
- 必须导入模块
abc
- 抽象类不可以实例化,必须继承后实例化,继承的子类需要实现所有的继承来的抽象方法
- 作用为设定类的标准
- 必须导入模块
1 | import abc |
组装类
函数名可以作为变量使用
1 | class User(): |
Package
package is a collection of modules, which must be included with a file called __init__.py
how to import a package
import all include
__init__.py
1
2
3
4import package_name
package_name.function_name()
package_name.class_name.function_name()only import specify module,except
__init__.py
1
2
3
4import package_name.module_name as md1
md1.function_name()
md1.class_name()another way import should be mentiond
1
from package_name import *
the way import only import function and class which in
__init__.py
module
a module is a file contains python code.it’s suffix with .py
why we need module?
- shrink program,make it easy to maintain
- module can be reused
- used as a namespace,reduce name conflict
how to use module?
import directily
1
2
3
4import module_name
module_name.function_name()
module_name.class_name()if the module name prefix with num such as 2.py
1
2
3
4
5
6import importlib
variable = importlib.import_module("02")
variable.function_name()
variable.class_name()use as rename module when the name of module is long
1
import module_name as somename
import module’s class or function,not whole module
1
2
3
4from module_name import someclass,somefunction
variable1 = someclass()
variable2 = somefunction()import all class and function
the benifit of it is writing class or function directily without module name prefix
1
2
3from module_name import *
variable = someclass()
where modules store?
default location
1
2
3
4import sys
for i in sys.path:
print(i)add own module location
1
2
3import sys
sys.path.append(directory)
the entrance of code
- in genreal,all entrance of code should be started with this
- it can control whether to execute some code,if used as a code which will be execute,if used as a module which will not be execute
1 | if __name__ == "__main__": |
Error catch
some days ago,i really don’t know why we need to catch error.in my mind,i think we should not write code with error.until one day,i get a problem,i need to create a temporary table first and then delete it every time the script run.and the error appeard.some times the table isn’t exist,when execute the delete code,the program broken.at last i use error catch to avoid the error
eg:get user type in
1 | try: |
- syntax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21try:
...
# can raise error by hand
raise some_error_type
# if it is the error below(tuple),execute this code
except (error_type1,error_type2...):
...
# exit() can exit the program
exit()
# we can print error infomation
except ZeroDivisionError as e:
print(e)
# Exception is the supper of all except type
except Exception as e:
...
# if not in the error above execute this code
else:
...
# what ever error happend,will execute this code
finally:
...
Time mudule
1 | import time |
1 | import timeit |
1 | import datetime |
OS module
associated with operate system
three important modules:
- os
- os.path, used for path
- shutil, used for directory,file
1 | import os |
1 | import os.path as op |
1 | import shutil |
Random module
1 | import random |
Functional programming
features:
- function can be used as a parameter
- function can be used as return value
lambda
lambda exprssion
- begin with lambda
- have zero or more parameter
- use : split lambda with expression
- no return keyword
1 | la = lambda x: x * 100 |
high-level function
1 | def get_name(): |
1 | # normal function |
map
map(func,*iterables)
1 | l1 = [i for i in range(10)] |
reduce
notice:
- need import module
- function need two parameters
- function need return value
principle:
reduce(1,2,3) = f(f(1,2),3)
1 | from functools import reduce |
filter
notice:
- function need return a boolean
- filter return a class object which can be iterabled
filter(function,*iterables)
1 | l1 = [i for i in range(10)] |
sorted
number sorted
1 | import random |
charactor sorted
1 | l1 = ["sda","dev","HOME","Alian","alias"] |
Closure package
B function defined inside A function,and B function as a return vlaue,all parameters of A can be used by B,it is called closure
1 | def A(*args): |
Decorator
Decorator is a high-level function,i can return a function.
feature:
- extend origion function without change its code
- use
@
to called a decorator
1 | import time |
Partial function
return a new function with some of its parameters fixed
1 | import functools |
zip
combine two iterable object into several tuples
1 | l1 = [i for i in range(1,10)] |
enumerate
give each iterable object a index and return several tuples,notice that the index can be customized
1 | l1 = [i for i in range(1,10)] |
collections module
- namedtuple: it can limit the number of tuple
- deque: it is much faster than list
- defaultdict: no error report when query none exist key
- Counter: regard string as a iterable dict
1 | import collections |
1 | import collections |
1 | import collections |
1 | import collections |
File operate
open
- mode
- r: read only
- w: new write,will erase origional file
- x: open exist file,if not error reportd
- a: append mode
- b: binary write
- t: file mode open
- +: read and write
in this way, we need to close file handle by hand
1 | dir = r"/home/narcissus/Desktop/遍历游标的三种方式.md" |
in this way, file handle will be closed automatically
1 | dir = r"/home/narcissus/Desktop/遍历游标的三种方式.md" |
read only one line,so should be carefully
1 | dir = r"/home/narcissus/Desktop/遍历游标的三种方式.md" |
read all lines
1 | dir = r"/home/narcissus/Desktop/遍历游标的三种方式.md" |
read each word
1 | dir = r"/home/narcissus/Desktop/遍历游标的三种方式.md" |
write
- write: only support string
- writeline: can write list directily
1 | import os |
pickle module
it is used for persistence file, can save program’s information to disk while the program runing
feature:
- it can store infomation immediately
- it can store infomation with format unchanged
function:
- pickle.dump: write
- pickle.load: read
notice:
use binary mode to write or read file
1 | import pickle,os |
Log
why we need log?
recording some information at important points, suitable log information can let us to know program running statius
but that isn’t to say log is much more much better,because io operation will slow down program.
there are several log level:
- debug
- info
- notice
- warning
- error
- critical
- alert
- emergency
log include:
[time location level content]
good log module:
- log4j -> java
- log4php -> php
- logging -> python
python logging module
level:
- debug
- info
- warning
- error
- critical
default log level:
- specify a log level in program
- only log level which equal or high above than specified level will be write in log
usage:
specify default log level
only logging once at first time executes
feature:
- specify the default log level
- output: sys.stderr
- default level: warning
- format: level:log_name:content
1 | logging.basicConfig(**kwargs) |
eg:
1 | import logging |
use level function
1 | logging.debug(msg, *args, **kwargs) |
eg:
1 | import logging |
use log function
1 | logging.log(level, *args, **kwargs) |
eg:
1 | import logging |
complete example
1 | import logging |
by hand usage
- logger: a interface of log produces log
- handler: decide where log stores
- filter: what should be displayed
- formatter: format
logger:
1 | Logger.setLevel() |
and so on …..
Json
convert:
- json.dumps(): python -> json
- json.loads(): json -> json
read and write with file:
- json.dump(): write to file
- json.load(): read from file
1 | import json,os |
Multi threads
process vs thread:
process totally different,but thread will share something.
process builds with threads
basic usage
syntax:
1 | import threading |
notice:
the type of args is tuple
daemon thread
when process stops the daemon thread will stop immediately
syntax:
1 | import threading |
shared variables
it is appeard when several threads access one variable at the same time, it will lead wrong result. In order to resolve this problem, we can lock the use of variable
syntax:
1 | lock = threading.Lock() |
without lock
1 | import threading |
use lock
1 | import threading |
thread safe
if one variable to be used by multi threads at the same time without lock variable but no problem happend, it is called thread safe.
not thread safe: list, set, dict
thread safe: queue
deadlock
two lock both not release, lead to both waitting, deadlock appeard, leading program dead
muiti processes
we know multi threads will cause problem usually, but there are several method more useful than multi threads:
- subprocess
- multiprocessing
- concurrent.futures
iterable/iterator
difference:
iterable -> directly used by for loop
iterator -> not only used by for loop but also can be used by next function
how to distinct each other:
1 | from collections import Iterable,Iterator |
convert iterable to iterator:
1 | from collections import Iterable,Iterator |
generator
feature:
- product data which used by for loop
- at the end of generator raise StopIterationError
- can be used by next() function
why we need generator?
all data are calculated step by step when in need, don’t store in memory, use cpu instead of memory. range() is a generator,so we need use it often, it is more useful than list.
how to make a generator
()
- yield: yield can stop loop until next iterate
use ()
1 | lt = [i for i in range(10)] |
use yield
1 | # normal usage |
coroutines
coroutines is much more useful than multi threads, it’s need less resource, we can regard it as a generator or a function which can be stopd
how to realize it?
- yield: return result
- send: send args to generator
- yield from: as a middle hand transfer message
yield x: return x
x = yield: get x value from send() function
1 | def test_coroutine(): |
yield from
1 | def test_coroutine(st): |
async/wait
1 | import asyncio |
concurrent.futures
- use subprocess, run several python interpreter. each subprocess can use a core of cpu, all core of cpu can be used 100%
- use multithreads, as we know python can only use one thread at one time, so it uses the same time as one process, and each of thread can not pull use cpu
ThreadPoolExecutor
although my cpu only have 4 core 8 thread, but each cpu didn’t be full used, it is because python can only run one thread at one time, threadpool is also thread.
1 | from concurrent.futures import ThreadPoolExecutor |
use map
1 | from concurrent.futures import ThreadPoolExecutor |
ProcessPoolExecutor
all core of cpu can be used 100%
1 | from concurrent.futures import ProcessPoolExecutor |
regular expression
there are two methods
compile re to a object
1
2
3
4
5
6import re
s = "Hello, Join. where did you go? 123,hk123,H89Hk"
p = re.compile("[0-9]{1,}")
m = p.findall(s)
print(m)use re directory
1
2
3
4
5import re
s = "Hello, Join. where did you go? 123,hk123,H89Hk"
m = re.findall("[0-9]{1,}",s)
print(m)
ignore case
1 | import re |
- substitute
1 | import re |
- catch chinese
1 | import re |
- catch no chinese
1 | import re |
Xpath
it is used to find xml file
syntax:
/
: root node//
: two node.
: current node..
: father node@
: property
net program
network model:
- 7 layers model
- Layer 7 - Application
- Layer 6 - Presentation
- Layer 5 - Session
- Layer 4 - Transport
- Layer 3 - Network
- Layer 2 - Data Link
- Layer 1 - Physical
- 4 layers model
- Layer 4 - Application
- Layer 3 - Transport
- Layer 2 - Network
- Layer 1 - Link
ftp
leaning website: link
Python ftplib
python ftplib is a module that implements the client side of the FTP protocol. It contains an FTP client class and some helper functions.Python FTP clas
The ftplib.FTP() creates a new instance of the FTP class. When host is given, a connection to the host is made with the connect() method.
example:
in my archlinux, i start vsftpd.service first
1 | sudo systemctl start vsftpd |
and then change the default config /etc/vsftpd.config
to enable local user login
at last i write a ftp python file
1 | import ftplib |
how it works?
process: user mail —-> mail proxy —–> mail server —–> user
agent: ————>mua————–>mta—————>mda
protocal: —————–>SMTP————->POP3/IMAP
MUA: MailUserAgent, user send mail to proxy
MTA: MailTransferAgent, catch mail from proxy to mail server
MDA: MailDeliveryAgent, deliver mail from server to user
how to use it:
there are two modules
- email: used to modify mail
- smtplib: used to send mail
the following is a simple text mail example.
1 | import smtplib |
the following is a text format mail with additional file
1 | import smtplib |
the following is a html format mail example.
1 | import smtplib |
alternative choose html format or text format, because some fo device can not display html format
1 | import smtplib |
the end! I am really happy that i learn all of them. It is really awesome,nice.