最近好多基础都快忘记了,重新跟着网上的教程从新走一遍,顺便做个记录
文章目录
python解释器
python的解释器包括CPython,IPython,PyPy,Jython,IronPython最常用就是CPython。
python基础
输出
print()函数也可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出:
>>> print('The quick brown fox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog
整数
Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等,整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。
字符串
字符串可以用’‘或者""来表示,如果碰到特殊字符含义可以用转义字符\,
Python还允许用r’‘表示’'内部的字符串默认不转义
>>> print('\\\t\\')
\ \
>>> print(r'\\\t\\')
\\\t\\
允许用’’’ ‘’'来表示多行字符
>>> print('''line1
... line2
... line3''')
line1
line2
line3
空值
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值,然后再数组中一个空的数组也可做如下判断:
>>> data = []
>>> True if data else False
False
除法
#精确除法
>>> 10 / 3
3.3333333333333335
#得到的结果一定是浮点数
>>> 9 / 3
3.0
#取整
>>> 10 // 3
3
#求余
>>> 10 % 3
1
字符串
ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符
>>> ord('w')
119
>>> chr(119)
'w'
以Unicode表示的str通过encode()方法可以编码为指定的bytes
但是如果再文本中编辑的时候带有中文的时候需要再文件头加上一下,但是windows会忽略这个
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
接下来是几种常见的格式化字符串
占位符 | 替换内容 |
---|---|
%d | 整数 |
%f | 浮点数 |
%s | 字符串 |
%x | 十六进制整数 |
list
基本操作
data = []#初始化数组
data.append(i)#添加元素i到列表的最后一个i
data.insert(1, 'Jack')#插入元素到指定位置
data[-1]#访问列表的最后一个
data.pop()#返回列表的最后一个元素,并将他从列表中删除
data.pop(i)#返回第i个位置的元素,并将他从列表中删除
tuple
tuple和list大部分都差不多,但是tuple一旦初始化就不能修改,类似定义一个常量,但是在定义只有一个数字的情况下需要如下定义
data = ()#定义一个空的tuple
data = (1)#返回1
data = (1,)#返回(1)
还有需要注意的是tuple中的不变指的是引用地址不变,假如tuple里面混入一个list,当list的元素发生变化的时候是不会被判定成tuple的改变的,如下
>>> data = (1,2,[3,4])
>>> data[2][0]=5
>>> data[2][1]=6
>>> data
(1, 2, [5, 6])
>>>
还有就是tuple的检索速度在数据量大的情况下是要比list要快的,具体涉及到了内存分配的问题
dict
dict是键-值(key-value)存储,有点类似json或者其他数据的map,基本操作
d = {'wr':90,'wxy':90}#初始化dict
d['wr']#获取相对应的value值
d.get('wr',y)#获取相对应的value值,后面可以自定义一个值假设没找到的话返回规定的值y
d.pop('wr')#弹出当前值并且删除对应的value
和list相比的优缺点:
优点就是查找的速度快,缺点就是占用的空间大,典型的空间换时间
set
set的最大特点就是不能重复,具有集合的无序性所以挺多去重操作可以用到,下面是基本操作
data = set([1,2,3])#初始化一个set
data.add(4)#添加一个元素
data.remove(4)#删除一个元素
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2#类似集合的交集操作
{2, 3}
>>> s1 | s2#类似集合的并集操作
{1, 2, 3, 4}
条件判断
if 条件:
条件为true执行
else:
条件为false执行
#简写
条件为true执行 if 条件 else 条件为false执行
循环
python循环一共有两种for 和while
for i in range(10):
print(i)
j = 0
while j < 10:
print(j)
切片操作
>>>a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>>a[:] #从左往右
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>a[::]#从左往右
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>a[::-1]#从右往左
>>> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>>>a[1:6]
>>> [1, 2, 3, 4, 5]
>>>>a[1:6:-1]
>>> []
>>>>a[:6:-1]
>>> [9, 8, 7]
列表生成式
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
生成器
在创建一个列表的时候如果直接把列表生成出来会造成大量的内存浪费,但是如果把它变化成生成器就可以减少大量空间的浪费
在列表生成式中两个相差就只有[]和()的区别
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
如果在递归函数中的话把return改成yield,所以如果一个函数中包括yield那这个函数就不是普通的函数而是一个生成器
高阶函数
函数本身也可以赋值给变量,即:变量可以指向函数
map
第一个参数是一个函数对象可以是自定义的函数对象也可以是python内置的函数对象,第二个是需要处理的数据
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
和map的用法差不多,第一个参数是一个函数对象可以是自定义的函数对象也可以是python内置的函数对象,第二个是需要处理的数据,不过不同的是reduce把结果继续和序列的下一个元素做累积计算
>>> from functools import reduce
>>> def add(x, y):
... return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
filter
字面上的理解就是拦截器,至于用法其实和map差不多,只不过filter对参数里的每一个数据经过函数的判断然后返回False或者True,根据true或者false来判断是否保留
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 结果: ['A', 'B', 'C']
sorted
sorted可以有三个参数,第一个参数就是需要排序的对象,第二个就是排序的key值,第三个就是排序的正序或者逆序
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
lambda
def f(x):
return x * x
lambda x: x * x
装饰器(Decorator)
装饰器的定义就是在代码运行期间动态增加功能的方式,理解一下就是当下面我不想要修改now的方法,但是在某一次使用now的时候我想输出当前的调用这就产生了修饰器的作用,在调用now的同时还调用了log方法
import time
def log(func):
def wrapper(*args,**kw):
print("现在时间是%s"%(time.strftime('%Y.%m.%d %H:%M:%S ',time.localtime(time.time()))),end='')
print("您调用了%s"%(func.__name__))
return func(*args,**kw)
return wrapper()
@log
def now():
print("hello world")
now
#运行结果为
#现在时间是2020.03.18 20:28:16 您调用了now
#hello world
但是如果当Decorator自己运行的时候本身就需要一个参数的时候,我的理解就是在前后端校验密码的时候可以确认用户是否登入的例子,但是这里的例子,不过这里就需要多加一层的嵌套来返回当前log接受的值
偏函数(functools)
简单来说就是创建一个新的函数,可以固定原来那个函数的部分参数(重新设置一个默认值)
>>> import functools
>>> int2 = functools.partial(int, base=2)
面对对象
slots
假如你在创建一个对象的时候想要限制这个对象的属性,就可以使用当前这个参数来规定具体使用如下
class Student(object):
__slots__ = ('name', 'age')
当选择创建不属于slots里面的参数的属性的时候就会爆出一个AttributeError的错误
多重继承
假如要实现一个事务的多种形态时候,就比如鸟是动物,可以飞的动物,老虎是动物但是不能飞,就可以用到多重继承的概念,子类可以扩展更多父类的功能
定制类
str:在print对象的实例的时候会返回对象的内存地址,如果你将class里面的str重新定义的话就能返回一个非常易于观看的对象属性
repr:和str是非常相似的,两者的主要区别就是str返回的是用户看到字符串,而repr返回的是开发者看到的字符串,我的理解就是一个在编译器里不需要调用就可以输出
iter:如果希望对象能返回一个迭代对象,就需要实现以下当前的方法,然后循环就会不停的找下一个,直到没有的时候返回一个错误
getitem:可以让对象像数组一样调用使用切片或者下表访问对象的参数
getattr:有时候我们在访问对象一个不存在的属性的时候就会报错,但是当我们重写了这个方法之后,在调用不存在的属性的时候,他就会返回一个默认的自定义的值
call:这个属性可以让对象像一个方法一样被调用
枚举类
Python提供了Enum类来实现这个功能
io流
python内置了open方法来打开文件对象,同时可以使用with来取消close代码
其中read方法会直接读取全部文件的内容,但是如果文件有10个g那内存可能就爆了,所以还提供了一种read(size)的方法用来每次读取多少大小的文件,或者readlines来返回每一行的数据,这个返回的是一个可迭代的对象,意思就是它可以用for来操作
如果读取的文件是二进制的,就需要用rb模式来打开
open('文件路径', 'rb')
如果是非utf-8编码的文件则需要指定他的编码格式
open('/Users/michael/gbk.txt', 'r', encoding='gbk')
StringIO和BytesIO
很多时候数据的读写不一定是在磁盘中,也可以是在内存中,
from io import StringIO
f = StringIO()
f.read("写入的内容")
f.getvalue()#就是得到当前写入的字符
同样如果操作二进制数据
from io import BytesIO
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
f.read()
操作文件目录
python提供了os来操作
# 查看当前目录的绝对路径:
os.path.abspath('.')
'/Users/michael'
# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
os.path.join('/Users/michael', 'testdir')
'/Users/michael/testdir'
# 然后创建一个目录:
os.mkdir('/Users/michael/testdir')
# 删掉一个目录:
os.rmdir('/Users/michael/testdir')
#合成路径的时候
os.path.join()
#拆分路径的时候,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名
os.path.split()
#返回文件的后缀名
os.path.splitext()
('/path/to/file', '.txt')
# 对文件重命名:
os.rename('test.txt', 'test.py')
# 删掉文件:
os.remove('test.py')
序列化
在运行中对象的创建都是在内存中完成的,所以当程序一结束对象所占的内存就被操作系统回收,所以Python提供了pickle模块来实现序列化,对象被序列化之后就可以被储存下来或者传输
import pickle
d = dict(name='Bob', age=20, score=88)
pickle.dumps(d)#序列化
pickle.loads()#返序列化
python还提供了json模块来完成json和对象的转换,如果是dict可以直接进行转换,但是我们平时用的一般是class的实例对象,所以我们需要告诉他是如何转换的,简单来说就是先转换成dict然后在转成json
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
进程和线程
多进程
multiprocessing是python用来提供跨平台版本的多进程模块。
多线程
常用的内建模块
datetime
date基本用法
#返回日期
>>> a = date.today()
>>> a
datetime.date(2020, 4, 8)
>>> a.year
2020
>>> a.month
4
>>> a.day
8
#两个日期比较
>>> a=datetime.date(2017,3,1)
>>> b=datetime.date(2017,3,15)
>>> a.__eq__(b)#等于
False
>>> a.__ge__(b)#大于等于
False
>>> a.__gt__(b)#大于
False
>>> a.__le__(b)#小于等于
True
>>> a.__lt__(b)#小于
True
>>> a.__ne__(b)#不等于
True
#两个日期差多少
a = datetime.date(2020, 4, 4)
b = datetime.date(2020, 4, 11)
a.__sub__(b)
datetime.timedelta(7)
#返回元组格式
a.isocalendar()
(2020, 4, 4)
#返回YYYY-MM-DD格式
a.isoformat()
'2020-04-04'
#返回星期数
a.isoweekday()
#返回标准时间
datetime.date.fromtimestamp(时间挫)
#格式话写法
a = datetime.date(2020,4,4).__format__('%Y-%m-%d')
time基本用法
datetime基本用法
#返回当前时间
datetime.now()
datetime.datetime(2020, 4, 8, 21, 42, 16, 885618)
#返回UTC时间元组
a.utctimetuple()
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=8, tm_hour=21, tm_min=43, tm_sec=12, tm_wday=2, tm_yday=99, tm_isdst=0)
collections
Counter:简单来说就是统计每个函数出现的次数
from collections import Counter
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
c = Counter(colors)
>>> c
Counter({'blue': 3, 'red': 2, 'green': 1})
namedtuple:是tuple的一个子类,可以用来自定义一个tuple对象,就比如定义坐标写个类大题小作,这样就可以用这个来设置
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
#然后就可以用p.x和p.y来表示了
deque:python内置的双向队列,刷题的时候用的挺多
from collections import deque
a = deque()
#操作方式和list差不多,不过它也支持popleft和popright从左侧或者右侧弹出数据
defaultdict:和dict的用法差不多,但是dict在默认没有找到key的情况下会返回一个错误,但是defaultdict就会返回一个你设置的默认值
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
OrderedDict:看名字也应该猜到意思了,平时使用的dict是一个无序,而OrderedDict返回的是一个有序的,他会按照插入的顺序排序而不是按照key的值排序
Counter:返回一个元素在字符串或者列表中出现次数
from collections import Counter
print(Counter("adbalwiuhfialdbhfluabweurfy"))
》》》Counter({'a': 4, 'b': 3, 'l': 3, 'u': 3, 'f': 3, 'd': 2, 'w': 2, 'i': 2, 'h': 2, 'e': 1, 'r': 1, 'y': 1})```
###### 3. hashlib
MD5:简单来理解就是hashlib提供了一个md5的加密算法
```python
import hashlib
md5 = hashlib.md5()
md5.update('how to use md5 in python hashlib?'.encode('utf-8'))
#它也可以分两次加载所需要加密的顺序
md5.update('how to use md5 in '.encode('utf-8'))
md5.update('python hashlib?'.encode('utf-8'))
hmac
python自带的hmac实现了hmac算法下面是他的简单使用,需要注意的是key参数和message参数在传入之前都需要是bytes,所以需要传入
import hmac
a = b'wangrui'
k = b'123'
h = hmac.new(k,a,digestmod='MD5')
h.hexdigest()
'dc9ff928cd82a2077359e2fe012f3d40'
itertools
groupby:他提供了一个把相邻的重复元素提取出来的操作
import itertools
for i,j in itertools.groupby(['a','a','b','b','c','c','a','a']):
... print(i,list(j))
...
a ['a', 'a']
b ['b', 'b']
c ['c', 'c']
a ['a', 'a']
#可以通过返回相同的key来做不区分大小写的操作
>>> for i,j in itertools.groupby(['a','a','b','b','c','c','a','A'],lambda c:c.upper()):
... print(i,list(j))
...
A ['a', 'a']
B ['b', 'b']
C ['c', 'c']
A ['a', 'A']