现有字典d={‘a’:24,‘g’:52,‘i’:12,‘k’:33} 按value排序
d={‘a’:24,‘g’:52,‘i’:12,‘k’:33}
sorted(d.items(), key=lambda x:x[1])
python中内置的数据结构有几种?
- 整型 int、 长整型 long、浮点型 float、 复数 complex
- 字符串 str、 列表 list、 元祖 tuple 字典 dict 、 集合 set
- Python3 中没有long,只有无限精度的 int
Python代码实现删除一个list里面的重复元素(三种)
a = [1,1,2]
for遍历
set(a)转
fromkeys() — list(dict().fromkeys(a))
一行代码求1-101的和
sum(range(1,101))
eval和exec的区别
eval处理字符串中的表达式,exec是处理字符串中的代码,
eval有返回值,exec没有返回值
软连接和硬链接的区别
创建 软连接 ln -s 【源文件或目录】 【目标文件或目录】
创建 硬链接 ln 【参数】 【源文件或目录】 【目标文件或目录】
软连接相当于快捷方式,删除源文件以后则失效,硬链接在背删除源文件以后并不会受到影响。
软链接:
- 1.软链接是存放另一个文件的路径的形式存在。
- 2.软链接可以 跨文件系统 ,硬链接不可以。
- 3.软链接可以对一个不存在的文件名进行链接,硬链接必须要有源文件。
- 4.软链接可以对目录进行链接。
硬链接:
- \1. 硬链接,以文件副本的形式存在。但不占用实际空间。
- \2. 不允许给目录创建硬链接。
- \3. 硬链接只有在同一个文件系统中才能创建。
- \4. 删除其中一个硬链接文件并不影响其他有相同 inode 号的文件。
VI编辑器中查找替换
:%s/p1/p2 将全文中所有p1均用p2替代
😒/p1/p2/g 将当前行中所有p1均用p2替代,若要每个替换都向用户询问则应该用gc选项
:n1,n2s/p1/p2/g 将第n1至n2行中所有p1均用p2替代
Python新式类与经典类(旧式类)的区别
Python中类分两种:旧式类和新式类:
➤新式类都从object继承,经典类不需要。
➤新式类的MRO(method resolution order 基类搜索顺序)算法采用C3算法广度优先搜索,而旧式类的MRO算法是采用深度优先搜索
➤新式类相同父类只执行一次构造函数,经典类重复执行多次。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M976PZ4V-1572871017273)(C:\Users\qy\AppData\Roaming\Typora\typora-user-images\1571725435714.png)]
如何删除键和合并两个字典
del 删除
update 合并
观察A0,A2,到An的值
A0 = dict(zip((‘a’,‘b’,‘c’,‘d’,‘e’),(1,2,3,4,5)))
A0
{‘a’: 1, ‘b’: 2, ‘c’: 3, ‘d’: 4, ‘e’: 5}A1= range(10)
A1
range(0, 10)
A5 = {i:ii for i in A1}
A5
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6 = [[i, ii] for i in A1]
A6
[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]A2 = [i for i in A1 if i in A0]
A2
[]
依次执行,print©会输出什么?
a = 10
b = 20
c = [a]
a = 15
print©
[10]
对于字符串、数字,传递的是相应的值
X是什么类型?
X = (i for i in range(10))
X<generator object at 0x000002660B8E0570>
X是生成器
用Python匹配HTML g标签的时候,<.>和<.?>有什么区别?
<.*> 贪婪匹配,会从第一个“<”开始匹配,一直到最后一个“>”
<.*?>非贪婪匹配,从第一个“<”匹配到第一个“>”
.?? 尽可能不匹配
cookie和session的区别
(1)cookie以文本文件格式存储在浏览器中,而session存储在服务端它存储了限制数据量
(2)cookie的存储限制了数据量,只允许4KB,而session是无限量的
(3)我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此它更安全
(4)设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
总结:如果我们需要经常登录一个站点时,最好用cookie来保存信息,要不然每次登陆都特别麻烦,如果对于需要安全性高的站点以及控制数据的能力时需要用会话效果更佳,当然我们也可以结合两者,使网站按照我们的想法进行运行。
session是基于cookie的,cookie关闭以后,session是无法使用的。
如何管理不同版本的代码
git 分布式版本版本控制管理器 gitleb
svn 同步式版本控制管理器
vcs
列举使用过的Python网爬虫所用到的网络数据包、解析数据包
- 网络数据包 urllib、urllib2、requests、httplib2
- 解析包 re、xpath(lxml)、beautiful soup、json、jsonpath、
数据包是下载数据的库
代码的运行结果
v = dict.fromkeys([‘k1’, ‘k2’],[])
v[‘k1’].append(666)
print(v)
v[‘k1’] = 777
print(v)
结果:
{‘k1’: [666], ‘k2’: [666]}
{‘k1’: 777, ‘k2’: [666]}
列表合并
a= list[]
b=list[]
- a+b 加入的是列表中的数据
- a.extend(b) 加入的是列表中的数据
- a.append(b) 加入的是列表
Python RE模块中search和match的区别
match()函数只检测RE是不是在string的开始位置匹配
search()会扫描整个string查找匹配,会扫描整个字符串并返回第一个成功的匹配
也就是说match())只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none
例如:
print(re.match(‘super’, ‘superstition’).span()) 会返回(0, 5)
print(re.match(‘super’, ‘insuperable’)) 则返回None
search()会扫描整个字符串并返回第一个成功的匹配
例如:print(re.search(‘super’, ‘superstition’).span())返回(0, 5)
print(re.search(‘super’, ‘insuperable’).span())返回(2, 7)
字典的key相同的时候,value怎么合并
x = { 'apple': 1, 'banana': 2 }
y = { 'banana': 10, 'pear': 11 }
# 需要把两个字典合并,最后输出结果是:
{'apple': 1, 'banana': 12, 'pear': 11}
# 利用cllections.Counter可轻松办到
一
>>> x = { 'apple': 1, 'banana': 2 }
>>> y = { 'banana': 10, 'pear': 11 }
>>> from collections import Counter
>>> X,Y = Counter(x), Counter(y)
>>> z = dict(X+Y)
>>> z
>>>from collections import Counter
>>>dict(Counter(x)+Counter(y))
二
>>> dict(Counter(dict1)+Counter(dict2))
{'a': 3, 'b': 11}
>>> x = {'a':1,'b':2}
>>> y = {'a':10,'b':20}
>>> from collections import Counter
>>> dict(Counter(x)+Counter(y))
{'a': 11, 'b': 22}
三
>>> for i in x:
... for j in y:
... if i == j:
... x[i]=x[i]+y[j]
... print(x)
...
{'a': 11, 'b': 2}
{'a': 11, 'b': 22}
使用Counter的时候,value值小于等于0的时候,字典的key和value都不会显示。
数据库的ACID特性
Atomic(原子性)
Consistency(一致性)
Isolation(隔离性)
Durability(持久性)
1、原子性:一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
2、一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
3、隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4、持久性:持久性也称永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
隔离性的四个级别:
修改事务的隔离级别:
set session transaction isolation level serializable/repeatable read/read committed/read uncommitted
串行化(serializable):通常保证可串行化调度。然而,一些数据库系统对该隔离性级别的实现在某些情况下允许非可串行化执行。最高隔离性级别。强制事务串行执行。可避免脏读、不可重复读、幻读的发生。
可重复读(repeatable read):只允许读取已提交数据,而且在一个事务两次读取一个数据项期间,其他事务不得更新该数据。但该事务不要求与其他事务可串行化。例如:当一个事务在查找满足某些条件的数据时,它可能找到一个已提交事务插入的一些数据,但可能找不到该事务插入的其他数据。保证在同一个事务中多次读取同样数据的结果是一样的。可避免脏读、不可重复读的发生。
读已提交(read committed):只允许读取已提交数据,但不要求可重复读。比如,在事务两次读取一个数据项期间,另一个事务更新了该数据并提交。一个事务只能读取已经提交的事务所做的修改。换句话说,一个事物所做的修改在提交之前对其他事务是不可见的。可避免脏读的发生。
读未提交(read uncommitted):允许读取未提交数据。这是SQL允许的最低一致性级别。事务中的修改,即使没有提交,对其他事务也是可见的。最低级别,任何情况都无法保证。
以上所有隔离性级别都不允许脏写(dirty write),即如果一个数据项已经被另外一个尚未提交或中止的事务写入,则不允许对该数据项执行写操作。
Python中类方法,类实例方法,静态方法有什么区别
-
类方法
-
类实例方法
-
静态方法
Python中yield的用法
yield类似于return,但是它再返回值以后程序不再向下运行,保存当前程序的运行状态,它的好处是不用一次计算所有元素,而是用一次算一次,可以节省很多空间。将yield用到函数中可以作为一个生成器。
Python中is和==的区别
Python中对象的三个基本要素是:id(身份标识),type(数据类型)和value(值)
is通过id来进行判断
==通过value值进行判断
怎么在自己的网页里让超链接在新窗口中打开
<a href="链接地址" target="_blank">链接描述</a>
其中,target的参数可以设置为:
_self:在当前窗口打开
_blank:在新的窗口打开
_top:在当前窗口上方打开
装饰器可以在不修改现有代码的情况下可以给你现有的类增加功能。
Xrange和 range的区别
xrange与range类似,只是返回的是一个"xrange object"对象,而非数组list。
1.range和xrange都是在循环中使用,输出结果一样。
2.range返回的是一个list对象,而xrange返回的是一个生成器对象(xrange object)。
3.xrange则不会直接生成一个list,而是每次调用返回其中的一个值,内存空间使用极少,因而性能非常好。
_和__的区别
Python中单下划线和双下划线的区别:
单下划线
import * 不导入前面带下划线的私有变量,但是模块的私有变量其实是可以访问的
使用单下划线(_one_underline)开头表示方法不是API的一部分,不要直接访问
例如:_func
:一种约定,用来指定私有变量或私有函数(private)
双下划线是私有的,类中属性私有化可以在前面加双下划线,Python这么进行设计主要是为了避免子类覆盖父类的方法
前后加双下划线
Python内部自己调用的,比如我们可以调用len()函数来求长度,其实它后台是调用了__len__()方法。一般我们应该使用len,而不是直接使用__len__():
__func__
:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突。
在定义函数的时候,在函数的括号后面 加 -> 指定返回数据的类型
什么是闭包
一般用于装饰器,可以提高代码的可重复性。
它可以提取到函数内部的变量,另一个就是可以让这些变量的值始终保持在内存中,不会在外部函数调用后被自动清除。
多层函数嵌套,(函数里面还有定义函数,一般是两个),往往内层函数会用到外层函数的变量,把内层函数以及外部函数的变量当成一个特殊的对象,这就是闭包。闭包比面向对象更纯净、更轻量,既有数据又有执行数据的代码;比普通函数功能更强大,不仅有代码还有数据。
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
Python中的垃圾回收机制
1.引用计数:创建一个新的对象,它每被使用一次,引用计数+1,如果引用计数为0,则会被删除
2.标记-清除:如果出现了循环引用的情况,循环引用一般出现在list,dict,set等容器类对象中,将其进行遍历,其中被引用的称之为可达的,反之为不可达的,清除那些不可达的
3.分代回收:建立在清除基础上的一种辅助回收容器对象 的GC()机制,它认为存在越久的对象作用越大,越不会对其进行回收,所以将对象一共分三个集合,第一代,第二代跟第三代,新生对象为第一代,当第一代的数量达到上限后,触发GC机制:可以进行回收的对象所占的内存被释放,不能回收的就移去第二代,第二代的数量达到上限的时候同样进行检测,不可回收的移到第三代。
http协议 幂等性的理解
**HTTP幂等方法,是指无论调用这个url多少次,都不会有不同的结果的HTTP方法。**也就是不管你调用1次还是调用100次,1000次,结果都是一样的(前提是服务器端的数据没有被人为手动更改。比如说,你数据库中的数据被手动更改过,那两次调用的结果肯定是变化的)。
HTTP GET、 DELETE、PUT、POST四种主要方法的幂等性
- GET
- GET请求是幂等的,多次的GET请求,不应该修改数据状态,只是查询。
- DELETE
- DELETE请求也具有幂等性,执行一次请求,删除id=1的记录,多次请求与一次请求的结果应该是一样的,最终的结果都是把id=1的记录删除
- PUT
- PUT意为修改记录,也具有幂等性,执行一次请求,将记录修改为特定状态,多次请求结果也是一样的
- POST
- POST请求不具有幂等性,通常为增加记录,每执行一次请求,都增加一条记录。
格式化字符串
%d,%i | 转换为带符号的十进制形式的整数 |
---|---|
%o | 转换为带符号的八进制形式的整数 |
%x,%X | 转换为带符号的十六进制形式的整数 |
%e | 转化为科学计数法表示的浮点数(e 小写) |
%E | 转化为科学计数法表示的浮点数(E 大写) |
%f,%F | 转化为十进制形式的浮点数 |
%g | 智能选择使用 %f 或 %e 格式 |
%G | 智能选择使用 %F 或 %E 格式 |
%c | 格式化字符及其 ASCII 码 |
%r | 使用 repr() 将变量或表达式转换为字符串 |
%s | 使用 str() 将变量或表达式转换为字符串 |
Python中的自省函数
dir()
返回传递给它的任何对象的属性名称经过排序的列表。如果不指定对象,则 dir() 返回当前作用域中的名称。
>>> import keyword
>>> dir(keyword)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'iskeyword', 'kwlist', 'main']
isinstance()
可以使用 isinstance() 函数测试对象,以确定它是否是某个特定类型或定制类的实例:
>>> isinstance("python", str)
True
type()
确定对象是字符串还是整数,或是其它类型的对象。
hasattr()/getattr()
确定对象是否具有指定的属性
>>> hasattr(id, '__doc__')
True
搜索引擎(ES集群)
说到开源搜索引擎一定要用的开源项目就是lucene,它不是搜索引擎产品,而是一个类库,而且是至今开源搜索引擎的最好的类库没有之一,因为只有它一个。lucene是用Java语言开发,基本上涵盖了搜索引擎中索引和检索两个核心部分的全部功能,而且抽象的非常好。
solr,这是一个完整的搜索引擎产品,当然它底层一定是基于lucene的
Elasticsearch(简称ES)是一个基于Apache Lucene™的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
正则表达式
“^” ^ 会匹配行或者字符串起始位置,有时候也会匹配整个文档的起始位置
“$” $ 匹配行或字符串的末尾
“\b” 不会消耗任何字符,只会匹配一个位置,常用于匹配单词的边界。 如 我想从字符串中"This is Regex"匹配单独的单词 "is" 正则就要写成 "\bis\b"
\b 不会匹配is 两边的字符,但它会识别is 两边是否为单词的边界
"\d" 匹配数字,
例如要匹配一个固定格式的电话号码以0开头前4位后7位,如0737-5686123 正则:^0\d\d\d-\d\d\d\d\d\d\d$
"\w" 匹配字母,数字,下划线.
例如我要匹配"a2345BCD__TTz" 正则:"\w+"
"." 匹配除了换行符以外的任何字符
这个算是"\w"的加强版了"\w"不能匹配 空格 如果把字符串加上空格用"\w"就受限了,看下用 "."是如何匹配字符"a23 4 5 B C D__TTz" 正则:".+"
"[abc]" 字符组 匹配包含括号内元素的字符
"*"(贪婪) 重复零次或更多
"+"(懒惰) 一次或更多次
"?"(占有) 重复零次或一次
"*?" 重复任意次,但尽可能少重复
"+?" 重复1次或更多次,但尽可能少重复
"??" 重复0次或1次,但尽可能少重复
"{n,m}?" 重复n到m次,但尽可能少重复
"{n,}?" 重复n次以上,但尽可能少重复
反义
"\W" 匹配任意不是字母,数字,下划线 的字符
"\S" 匹配任意不是空白符的字符
"\D" 匹配任意非数字的字符
"\B" 匹配不是单词开头或结束的位置
"[^abc]" 匹配除了abc以外的任意字符
Python2与Python3的具体区别
print
函数:(Python3中print为一个函数,必须用括号括起来;Python2中print为class)
通过input()
解析用户的输入:(Python3中input得到的为str;Python2的input的到的为int型,Python2的raw_input得到的为str类型)
统一一下:Python3中用input,Python2中用row_input,都输入为str
整除:(没有太大影响)(Python3中/表示真除,%表示取余,//表示地板除(结果取整);Python2中/表示根据除数被除数小数点位得到结果,//同样表示地板除)统一一下:Python3中/表示真除,%表示取余,//结果取整;Python2中带上小数点/表示真除,%表示取余,//结果取整
在 Python 3 中,range() 是像 xrange() 那样实现以至于一个专门的 xrange() 函数都不再存在(在 Python 3 中xrange() 会抛出命名异常)。
在 Python 2 中 xrange() 创建迭代对象的用法是非常流行的。比如: for 循环或者是列表/集合/字典推导式。
print 2中是关键字 3中是函数
编码 2是ASCII,3是utf-8
3将2中许多方法结果都整合成了可迭代对象
session与cookie的区别
(1)Cookie以文本文件格式存储在浏览器中,而session存储在服务端它存储了限制数据量。
(2)cookie的存储限制了数据量,只允许4KB,而session是无限量的
(3)我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此它更安全
(4)设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
总结:如果我们需要经常登录一个站点时,最好用cookie来保存信息,要不然每次登陆都特别麻烦,如果对于需要安全性高的站点以及控制数据的能力时需要用会话效果更佳,当然我们也可以结合两者,使网站按照我们的想法进行运行
回顾Python中的序列化和反序列化有哪些模块和方法
- pickle
- dump() 序列化对象为字节数据,并写入到文件中,
- dumps() 序列化对象为字节数据,并返回
- load() 从文件中加载字节数据,反序列化为对象
- loads() 从字节数据中反序列化为对象
- json
- dump() 序列化对象为字符数据,并写入文件中
- dumps() 序列化对象为字符数据,并返回
- load() 从文件找那个加载字符数据,并反序列化为对象
- loads() 加载字符数据,并反序列化为对象
read,readline,readlines的区别
read() : 一次性读取整个文件内容。推荐使用read(size)方法,size越大运行时间越长
readline() :每次读取一行内容。内存不够时使用,一般不太用
readlines() :一次性读取整个文件内容,并按行返回到list,方便我们遍历
一般小文件我们都采用read(),不确定大小你就定个size,大文件就用readlines()
在try…except中
raise抛出自定义异常
lambda函数的好处
匿名函数,可以接收任意多个参数(包括可选参数)并且返回单个表达式值的匿名函数。
1、lambda函数比较轻便,即用即扔,很适合需要完成某一项简单功能,但是这个简单的功能只在此一处使用,连名字都很随意的情况下;
2、lambda是匿名函数,一般用来给filter,map,reduce这样的函数式编程服务;
3、作为回调函数,可以传递给某些应用,比如消息处理等。
例如:lambda x: x*2
高阶函数map()中使用lambda函数:
map(lambda x:x ** 2, [1,2,3,4,5])
<map object at 0x0000014A5D7B7978>
a = map(lambda x:x ** 2, [1,2,3,4,5])
list(a)
[1, 4, 9, 16, 25]
map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
提供了两个列表,对相同位置的列表数据进行相加
map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
append和extend的区别
append:append会把新元素添加到列表末尾
extend:通过extend可以将另一个集合中的元素逐一添加到列表中
append接收的参数会直接添加到list中,一次只能是一个值,而expend接收的参数是一个list,会把这个list上所有元素都添加进去,而append若是接收一个list,会把这个list当做一个元素添加到当中去。
Sys.argv[ ]的作用
- 从程序外部获取参数
- 可以看作是一个列表,其第一个元素是程序本身,随后才依次是外部给予的参数。
读取csv文件的三种方式
with open as () f:
csv,DictReader(f)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-njliLHwq-1572871017276)(C:\Users\qy\AppData\Roaming\Typora\typora-user-images\1571793971083.png)]
pd.read_csv(path, encoding=‘utf-8’)
np.loadtxt(path, delimiter=‘,’, unpack=True, dtype=‘str’)
XML文件解析
bs:解析,
xpath:解析XML
enumerate的作用和用法
enumerate可以将一个可迭代对象或可遍历对象 组成一个序列索引,利用它可以同时获取索引和值。
list1 = [‘这’,‘是’,‘一个’,‘测试’]
for i,j in enumerate(list1):
… print(i, j)
…
0 这
1 是
2 一个
3 测试
Python的特点:
a.面向对象的【一切皆对象】
b.解释性语言
c.交互式语言【在终端进行命令的编程】
d.跨平台的语言【没有操作系统的限制,任何的操作系统都可以运行python代码】
Python的优缺点:
优点:
a.易于学习和维护【版本更新迭代】
b.广泛的标准库【提供了大量的工具】
c.可扩展性
d.数据库【mysql,sqlites3,mongodb,redis等数据库,Python中都有对应的模块】
e.GUI编程【图形化界面】
缺点:
a.运行速度慢【和c语言比较】
b.代码不能加密
dict和list之间的区别
1、dict查找和插入的速度不会因为key-value的增多而变慢,而list在每次查找的时候都是从头到尾进行遍历,当数据量大的时候,list的查找速度变慢。
2、dict需要占用大量的内存空间,内存浪费多,而list只相当于存储了字典中的key或者value,并且list数据是紧密排列
list:有序,可以存储重复元素,可以存储不同类型的元素,可变
tuple:有序,可以存储重复元素,可以存储不同类型的元素,不可变
dict:无序,key不重复,value可以重复,可以存储不同类型的元素【key只能是不可变的类型】,可变
set:无序,不可以存储重复元素,可以存储不同类型的元素,不可变
简述可迭代对象和迭代器之间的联系和区别
只能被for循环直接遍历的就是可迭代对象,例如:list,tuple
既能被for循环直接遍历的还能被next调用的是迭代器,
迭代器一定是可迭代对象,可迭代对象不一定是迭代器
但是可以通过iter将list,tuple等可迭代对象转换成迭代器
collections包下的两个类:
Iterable 可迭代对象
Iterator 迭代器
简述global和nonlocal的作用【举例说明】
#前提:变量重名的情况下使用的
global:全局的
num = 10
def show():
global num #声明当前num是全局的num变量
s = num + 1
num = 20
print(s)
print(num)
nonlocal:不是局部的,应用在闭包中【函数作用域和局部作用域】
def outer():
num = 10
def inner():
nonlocal num
num = 20
print(num) #20
#调用内部函数
inner()
print(num) #10
return inner
栈和队列的相同点和不同点
相同点:
a.都是线性结构
b.插入操作都限定在表尾进行
c.管理模式相同
d.插入和删除的时间复杂度都是O(1),在空间复杂度上是一样的
不同点:
a.删除数据的位置不同,栈的删除在表尾进行,队列的删除在表头进行
b.应用场景不同:
栈的应用场景:变量,函数,表达式的转换或者求值
队列的应用场景:计算机中各种资源的分配和管理
@property除了进行操作私有化属性外,还可以修改普通的成员函数,将普通的成员函数当做属性使用
调用函数的语法:对象.函数名
@property
def show(self):
解释下面变量的作用
XXX:普通变量,可以任意访问
_XXX:受保护变量,在实际项目开发中,尽量不要使用
__XXX:私有变量,只能在当前类中直接访问
__XXX__:一般用于系统的变量和函数的命名,尽量不要使用,例如:__name__ ,__init__
继承
一个类继承自另一个类,也可以说是一个孩子类/派生类/子类,继承自父类/基类/超类,同时获取所有的类成员(属性和方法)。
继承使我们可以重用代码,并且还可以更方便地创建和维护代码。Python 支持以下类型的继承:
-
- 单继承- 一个子类类继承自单个基类
-
- 多重继承- 一个子类继承自多个基类
-
- 多级继承- 一个子类继承自一个基类,而基类继承自另一个基类
-
- 分层继承- 多个子类继承自同一个基类
-
- 混合继承- 两种或两种以上继承类型的组合
简述实例【对象】属性和类属性
a.定义的位置不同:类属性直接定义在类中,实例属性定义在构造函数中
b.访问方式不同:实例属性必须通过对象访问,类属性可以通过对象或者类名访问
c.在内存中的出现的时机不同:类属性随着类的加载而出现,实例属性随着对象的创建而出现
d.优先级不同:如果类属性和实例属性重名的情况下,对象访问,则优先访问实例属性
e.使用场景不同:类属性一般用于表示共享数据,实例属性一般用来表示对象的特有数据
如果是多个对象的共享数据,则定义为类属性
如果是每个对象的特有数据,则定义为实例属性
不同的对象访问同一个类属性,指向的是同一块空间
不同的对象访问同一个实例属性,指向的是不同的空间
pandas中删除一行或一列 drop()方法
用法:DataFrame.drop(labels=None,axis=0, index=None, columns=None, inplace=False)
参数说明:
labels 就是要删除的行列的名字,用列表给定
axis 默认为0,指删除行,因此删除columns时要指定axis=1;
index 直接指定要删除的行
columns 直接指定要删除的列
inplace=False,默认该删除操作不改变原数据,而是返回一个执行删除操作后的新dataframe;
inplace=True,则会直接在原数据上进行删除操作,删除后无法返回。
因此,删除行列有两种方式:
1)labels=None,axis=0 的组合
2)index或columns直接指定要删除的行或列
分类模型
- knn
- LogisticRegression
- DecisionTree
- SVC
- RandomForest
- naive_bayes GaussianNB/MultinomialNB/BernollyNB
- VottingClassifier 集成学习
回归模型
- KNeighborsRegressor
- LinearRegression/Ridge/Lasso
- SVR(kerner={‘linear’, ‘rbf’, ‘poly’, ‘sigmoid’})
- DecisionTreeRegressor
- RandomForestRegressor
交叉验证
- cross_val_score()
网格搜索
- GridSearchCV
降维
- PCA
- LDA
文本转成词频
- TfidfVectorizor
Socket套接字(Python网络编程)
socket.socket([family[, type[, proto]]])
线程是并发还是并行,进程是并发还是并行
深拷贝和浅拷贝有什么区别
常见的反扒手段和解决方案
数据重复爬取的话,怎么处理
爬虫框架scrapy的工作原理
数据分析的代码块运行的时间的查看 代码块前加%time
os,sys,re
os是操作服务器的函数(比如创建文件),
sys是系统函数,re是正则
Nginx负载均衡
1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB…
2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB…
3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB…
4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。
Docker、
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
遵循的代码规范,距离说明要求。
PEP8
def add(a, list1=[]):
list1.append(a)
return list1
print(add(1))
print(add(2, [4, 5]))
print(add(3))
______________
[1]
[4, 5, 2]
[1, 3]
______________
http协议和https协议默认的端口
http默认端口80/8080
https默认端口443
请求头第一行: GET / HTTP / 1.1
响应头第一行: HTTP/1.1 200 OK
Python中的线程锁
Python中每次只有一个线程进行,无法实现真正意义上的多线程,使用多线程会影响程序运行的速度。
锁的好处:
确保了某段关键代码只能由一个线程从头到尾完整地执行
锁的坏处:
阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁
死锁如何避免?
我们可以使用time.time()来进行一个超时等待
线程本地变量
ThreadLocal 原理:实质上,线程本地变量并不是存储在ThreadLocal中,而是存放在ThreadLocalMap中,ThreadLocalMap是ThreadLocal中的一个静态内部类,也是Thread中的一个成员变量,每个线程有每个线程自己的ThreadLocalMap,因此是线程隔离的
keyerror:一般是使用了字典中不存在的key,才会报keyerror。
flask中的蓝图的使用
WSGI(Web Server Gateway Interface) 【WEB服务器网关接口】
flask中work实现wsgi
django可以自己实现wsgi
SQL优化的方法
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
2.尽量避免使用is null和is not null,会导致数据库引擎放弃索引,进行全表查询
3.尽量避免使用*,返回无用字段会降低查询效率,可以用具体要查询的属性代替*
4.尽量避免使用or,会导致数据库引擎放弃索引,进行全表查询
5.尽量避免使用%,尤其在字段的开头,会导致数据库引擎放弃索引,进行全表查询
数据库中的三大范式
第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。
第二范式:如果关系模式R满足第一范式,并且R的所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。
第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。
常用状态码
200 OK 请求成功
400 服务器端无法理解客户端发送的请求,请求报文中可能存在语法错误。
403 不允许访问,被服务器拒绝
404 没有被请求的资源,路径错误等
405 请求的方式不对,请求的方式有get、post、head、put……常用的为post和get。
500 内部资源出故障了,服务器端在执行请求时发生了错误。也可能是web应用存在bug或某些临时故障。
状态码为405表示请求的方式不对,请求的方式有get、post、head、put……常用的为post和get。
flask中的钩子函数
注册一个函数,在处理第一次请求之前运行
@app.before_first_request
注册一个函数,在处理每次请求之前运行
@app.before_request
注册一个函数,在每次请求之后运行,注册的函数最少含有一个参数,这个参数实际上为服务器的响应,且函数中需要返回这个响应参数
@app.after_request
django中的的钩子函数(中间件)
Request预处理函数:process_request(self,request)
Response后处理函数:process_response(self,request,response)
process_view预处理函数:(self,request,call_back,callback_kwargs,callback_args)
Exception后处理函数:process_exception(self,request,exception)
Template模版渲染函数:process_template_response()
os模块
os.walk() 查询当前path路径下的目录路径,所有子目录,非目录文件
os.listdir() 获取当前目录下的所有文件(不包含目录下的文件)
os.path.abspath(_file_)当前path文件所在目录
os.stat
django中的on_delete用法
参数:CASCADE:默认值,级联删除;
PROTECT:保护模式,如果采用该模式,删除的时候,会报错:ProtectedError
SET_NULL:置空模式,删除的时候,外键字段置空,前提就是blank=True, null=True
,定义该字段的时候,允许为空。
SET_DEFAULT:置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
SET:自定义一个值,该值当然只能是对应的实体了
索引的优点跟缺点
优点:
1.大大加快数据的检索速度;
2.创建唯一性索引,保证数据库表中每一行数据的唯一性;
3.加速表和表之间的连接;
4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
5.通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
缺点 :
1.索引需要占物理空间。
2.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。
Django设置Cookie的过期时间expires, max_age的格式
1. 若没有填写max_age,expires,默认都为None
此时该cooike为临时的,只存在浏览器内存中,关闭浏览器则自动删除
2. 只有max_age,则按秒计算过期时间,浏览器会存在本地缓存路径,并自动删除过期cookie
3. 只有expires,则按照时间字符串计算过期时间,浏览器会存在本地缓存路径,自动删除过期cookie
3. 若max_age和expires同时存在,则默认使用max_age
4. 如果设置的cookie时间小于计算机时间,浏览器则不提取cookie
Django执行原生SQL语句的方法
1.raw()方法执行原生sql语句
**# raw()方法执行原生sql(调用的类名不区分是谁,只要存在均可执行)**
2.直接执行自定义原生sql语句
*#直接执行自定义原生sql***(完全避开模型层,类似pymysql操作)**
Django中CBV和FBV
CBV:提高了代码的复用性,可以使用面向对象的技术;
可以使用不同的函数针对不同HTTP方法的处理,不需要再使用if语句进行判断,提高代码的可读性
with关键字的作用
with open() 打开文件的话,不管代码运行的情况如何,文件最终都会被关闭
单元测试中断言的方法(assert)
a = 5
assert (a>1)
prnt(‘断言成功,程序继续运行’)
assert (a>10)
print(‘断言失败,程序报错’)
断言正确则什么都不做,程序继续往下运行,但是断言错误就会报错。
ORM (Object Relational Mapping(ORM)
对象关系映射模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.
3.ORM的优势
ORM解决的主要问题是对象和关系的映射,它通常将一个类和一张表一一对应,类的每个对象对应表中的一条记录,类的每个属性
对应表中的每个字段.
ORM提供了对数据库的映射,不用直接编写SQL代码,只需操作对象就能对数据库的数据进行操作.
让开发人员专注于业务逻辑的处理,提高了开发效率.
4.ORM的劣势
在一定程度上牺牲程序的执行效率.
ORM的操作是有限的,也就是ORM定义好的操作是可以完成的,一些复杂的查询操作是完成不了。不能建数据库和删除数据库.
ORM用多了SQL语句就不会写了,关系数据库相关技能退化…
Linux中的文件权限更改操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6EyP6LoA-1572871017280)(C:\Users\qy\AppData\Roaming\Typora\typora-user-images\1572571124633.png)]
django ORM中filter和get的区别
get 的参数只能是model中定义的那些字段,只支持严格匹配
filter 的参数可以是字段,也可以是扩展的where查询关键字,如in,like等
返回值
get 返回值是一个定义的model对象
filter 返回值是一个新的QuerySet对象,然后可以对QuerySet在进行查询返回新的QuerySet对象,支持链式操作
QuerySet一个集合对象,可使用迭代或者遍历,切片等,但是不等于list类型(使用一定要注意)
异常
get 只有一条记录返回的时候才正常,也就说明get的查询字段必须是主键或者唯一约束的字段。当返回多条记录或者是没有找到记录的时候都会抛出异常
filter 有没有匹配的记录都可以
用get方法查询的时候,查询不到内容的时候会抛出异常,同样查询结果多余1条的时候也会抛出异常
filer若是查询不到数据,会返回一个空的查询集,查询到多余一条的时候会返回一个包含多个对象的查询集
Python中的list跟ndarry的区别
HTML设置目标页面在新窗口打开
在使用标签进行超链接跳转时,目标页面默认在当前页面中打开。
如果希望当前页面中所有超链接跳转页面的时候,都在新窗口中打开,那么只需要在head标签中设置 base标签,给base标签设置target属性即可.
`<``base` `href="" target="_blank">`
target属性:
- _self:在当前页面中打开
- _blank:新窗口中打开
分别解释迭代器跟生成器
进程、线程、协程
get_attr跟get_attrbute的区别
程序的签名算法
flask跟django框架的区别
- Django功能大而全,Flask只包含基本的配置 Django的一站式解决的思路,能让开发者不用在开发之前就在选择应用的基础设施上花费大量时间。Django有模板,表单,路由,认证,基本的数据库管理等等内建功能。与之相反,Flask只是一个内核,默认依赖于两个外部库: Jinja2 模板引擎和 Werkzeug WSGI 工具集,其他很多功能都是以扩展的形式进行嵌入使用。
- Flask 比 Django 更灵活 用Flask来构建应用之前,选择组件的时候会给开发者带来更多的灵活性 ,可能有的应用场景不适合使用一个标准的ORM(Object-Relational Mapping 对象关联映射),或者需要与不同的工作流和模板系统交互。
- Flask 在 Django 之后发布,现阶段有大量的插件和扩展满足不同需要 Django发布于2005年,Flask创始于2010年年中。
Tornado框架
tornado做即时通讯
一个普通的tornado web服务器通常由四大组件组成。
- ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中
tornado.ioloop.IOLoop.current()
就是默认的tornado ioloop实例。 - app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。
- handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。
- 路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。
Python requests.post方法中data与json参数区别
在通过requests.post()进行POST请求时,传入报文的参数有两个,一个是data,一个是json。
data`与`json`既可以是`str类型`,也可以是`dict类型。
区别:
1、不管json
是str
还是dict
,如果不指定headers
中的content-type
,默认为application/json
2、data
为dict
时,如果不指定content-type
,默认为application/x-www-form-urlencoded
,相当于普通form表单提交的形式
3、data
为str
时,如果不指定content-type
,默认为application/json
4、用data参数提交数据时,request.body
的内容则为a=1&b=2
的这种形式,用json参数提交数据时,request.body
的内容则为’{"a": 1, "b": 2}'
的这种形式
Django中接收的数据:json.loads(request.body)
原生的SQL语句查询
针对复杂查询来说, 通过QuerySet查询不是特别方便,则使用原生的SQL查询。
-
QuerySet提供两种原生SQL查询:
-
QuerySet.raw()
要求: 查询的字段必须是模型类中声明的字段,且必须存在主键列 。查询的结果是RawQuerySet类对象,可以迭代,元素类型是模型类对象。
另外, 查询sql语句中可以使用 “%s” 占位符, 在其它可以使用元组参数传值
raw_queryset = FruitEntity.objects.raw('select id, name,price from t_fruit where price < %s order by price DESC LIMIT %s, 10', (10, 0)) for fruit in raw_queryset: print(fruit)
-
QuerySet.extra()
extra()扩展查询, 针对QuerySet查询结果集中,额外增加查询条件或排序等相关操作。返回结果还是QuerySet对象
qs1 = FruitEntity.objects.extra(where=['price<%s'], params=['10']) qs2 = FruitEntity.objects.extra(where=['price<%s or name like %s'], params=['2', '果']) qs3 = FruitEntity.objects.extra(where=['price<%s or name like %s', 'source=%s'], params=['2', '果', '西安'])
-
-
使用django.db.connection数据库连接对象进行原生SQL查询
connection对象表示与数据库连接的对象, 可以通过connection连接对象获取游标cursor对象,再通过cursor的execute()/fetchall()/rowcount相关方法或函数来执行原生的SQL和执行的结果。
cursor = connection.cursor() cursor.execute('select * from t_fruit') for row in cursor.fetchall(): print(row)
cursor.execute('update t_fruit set price=2 where id=1') print(cursor.rowcount) connection.commit() # 提交更新
'{"a": 1, "b": 2}'
的这种形式
Django中接收的数据:json.loads(request.body)
原生的SQL语句查询
针对复杂查询来说, 通过QuerySet查询不是特别方便,则使用原生的SQL查询。
-
QuerySet提供两种原生SQL查询:
-
QuerySet.raw()
要求: 查询的字段必须是模型类中声明的字段,且必须存在主键列 。查询的结果是RawQuerySet类对象,可以迭代,元素类型是模型类对象。
另外, 查询sql语句中可以使用 “%s” 占位符, 在其它可以使用元组参数传值
raw_queryset = FruitEntity.objects.raw('select id, name,price from t_fruit where price < %s order by price DESC LIMIT %s, 10', (10, 0)) for fruit in raw_queryset: print(fruit)
-
QuerySet.extra()
extra()扩展查询, 针对QuerySet查询结果集中,额外增加查询条件或排序等相关操作。返回结果还是QuerySet对象
qs1 = FruitEntity.objects.extra(where=['price<%s'], params=['10']) qs2 = FruitEntity.objects.extra(where=['price<%s or name like %s'], params=['2', '果']) qs3 = FruitEntity.objects.extra(where=['price<%s or name like %s', 'source=%s'], params=['2', '果', '西安'])
-
-
使用django.db.connection数据库连接对象进行原生SQL查询
connection对象表示与数据库连接的对象, 可以通过connection连接对象获取游标cursor对象,再通过cursor的execute()/fetchall()/rowcount相关方法或函数来执行原生的SQL和执行的结果。
cursor = connection.cursor() cursor.execute('select * from t_fruit') for row in cursor.fetchall(): print(row)
cursor.execute('update t_fruit set price=2 where id=1') print(cursor.rowcount) connection.commit() # 提交更新