├── Python数据库编程.md ├── Python常用类库.md ├── PythonWeb开发.md ├── Python面向对象.md ├── Python爬虫.md ├── Python进阶.md ├── README.md └── Python基础.md /Python数据库编程.md: -------------------------------------------------------------------------------- 1 | 2 | * [1.什么是MySQLdb?](#1什么是mysqldb) 3 | * [2.如何连接数据库?](#2如何连接数据库) 4 | * [3.如何创建数据库表?](#3如何创建数据库表) 5 | * [4.如何执行数据插入?](#4如何执行数据插入) 6 | * [5.如何执行数据库查询操作?](#5如何执行数据库查询操作) 7 | * [6.如何更新数据库数据?](#6如何更新数据库数据) 8 | * [7.如何删除数据库数据?](#7如何删除数据库数据) 9 | * [8.如何使用数据库事务?](#8如何使用数据库事务) 10 | * [9.python如何操作redis?](#9python如何操作redis) 11 | * [10.如果redis中的某个列表中的数据量非常大,如何实现循环显示每一个值?](#10如果redis中的某个列表中的数据量非常大如何实现循环显示每一个值) 12 | * [11.什么是一致性哈希?Python中是否有相应模块?](#11什么是一致性哈希python中是否有相应模块) 13 | 14 | 15 | ## 数据库编程 16 | 17 | 18 | #### 1.什么是MySQLdb? 19 | 20 | MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的。 21 | 22 | #### 2.如何连接数据库? 23 | 24 | ``` 25 | #!/usr/bin/python 26 | # -*- coding: UTF-8 -*- 27 | 28 | import MySQLdb 29 | 30 | # 打开数据库连接 31 | db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 32 | 33 | # 使用cursor()方法获取操作游标 34 | cursor = db.cursor() 35 | 36 | # 使用execute方法执行SQL语句 37 | cursor.execute("SELECT VERSION()") 38 | 39 | # 使用 fetchone() 方法获取一条数据 40 | data = cursor.fetchone() 41 | 42 | print "Database version : %s " % data 43 | 44 | # 关闭数据库连接 45 | db.close() 46 | ``` 47 | 48 | #### 3.如何创建数据库表? 49 | 50 | ``` 51 | #!/usr/bin/python 52 | # -*- coding: UTF-8 -*- 53 | 54 | import MySQLdb 55 | 56 | # 打开数据库连接 57 | db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 58 | 59 | # 使用cursor()方法获取操作游标 60 | cursor = db.cursor() 61 | 62 | # 如果数据表已经存在使用 execute() 方法删除表。 63 | cursor.execute("DROP TABLE IF EXISTS EMPLOYEE") 64 | 65 | # 创建数据表SQL语句 66 | sql = """CREATE TABLE EMPLOYEE ( 67 | FIRST_NAME CHAR(20) NOT NULL, 68 | LAST_NAME CHAR(20), 69 | AGE INT, 70 | SEX CHAR(1), 71 | INCOME FLOAT )""" 72 | 73 | cursor.execute(sql) 74 | 75 | # 关闭数据库连接 76 | db.close() 77 | 78 | ``` 79 | 80 | #### 4.如何执行数据插入? 81 | 82 | ``` 83 | #!/usr/bin/python 84 | # -*- coding: UTF-8 -*- 85 | 86 | import MySQLdb 87 | 88 | # 打开数据库连接 89 | db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 90 | 91 | # 使用cursor()方法获取操作游标 92 | cursor = db.cursor() 93 | 94 | # SQL 插入语句 95 | sql = """INSERT INTO EMPLOYEE(FIRST_NAME, 96 | LAST_NAME, AGE, SEX, INCOME) 97 | VALUES ('Mac', 'Mohan', 20, 'M', 2000)""" 98 | try: 99 | # 执行sql语句 100 | cursor.execute(sql) 101 | # 提交到数据库执行 102 | db.commit() 103 | except: 104 | # Rollback in case there is any error 105 | db.rollback() 106 | 107 | # 关闭数据库连接 108 | db.close() 109 | ``` 110 | 111 | #### 5.如何执行数据库查询操作? 112 | 113 | Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据。 114 | 115 | fetchone(): 该方法获取下一个查询结果集。结果集是一个对象 116 | fetchall():接收全部的返回结果行. 117 | rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。 118 | 119 | #### 6.如何更新数据库数据? 120 | 121 | ``` 122 | #!/usr/bin/python 123 | # -*- coding: UTF-8 -*- 124 | 125 | import MySQLdb 126 | 127 | # 打开数据库连接 128 | db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 129 | 130 | # 使用cursor()方法获取操作游标 131 | cursor = db.cursor() 132 | 133 | # SQL 更新语句 134 | sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M') 135 | try: 136 | # 执行SQL语句 137 | cursor.execute(sql) 138 | # 提交到数据库执行 139 | db.commit() 140 | except: 141 | # 发生错误时回滚 142 | db.rollback() 143 | 144 | # 关闭数据库连接 145 | db.close() 146 | ``` 147 | 148 | #### 7.如何删除数据库数据? 149 | 150 | ``` 151 | #!/usr/bin/python 152 | # -*- coding: UTF-8 -*- 153 | 154 | import MySQLdb 155 | 156 | # 打开数据库连接 157 | db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 158 | 159 | # 使用cursor()方法获取操作游标 160 | cursor = db.cursor() 161 | 162 | # SQL 删除语句 163 | sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20) 164 | try: 165 | # 执行SQL语句 166 | cursor.execute(sql) 167 | # 提交修改 168 | db.commit() 169 | except: 170 | # 发生错误时回滚 171 | db.rollback() 172 | 173 | # 关闭连接 174 | db.close() 175 | 176 | ``` 177 | 178 | #### 8.如何使用数据库事务? 179 | 180 | ``` 181 | # SQL删除记录语句 182 | sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20) 183 | try: 184 | # 执行SQL语句 185 | cursor.execute(sql) 186 | # 向数据库提交 187 | db.commit() 188 | except: 189 | # 发生错误时回滚 190 | db.rollback() 191 | ``` 192 | 193 | #### 9.python如何操作redis? 194 | 195 | ``` 196 | 连接 197 | - 直接连接: 198 | import redis 199 | r = redis.Redis(host='10.211.55.4', port=6379) 200 | r.set('foo', 'Bar')    # 这里的方法与Redis命令类似 201 | print r.get('foo') 202 | - 连接池: 203 | import redis 204 | pool = redis.ConnectionPool(host='10.211.55.4', port=6379) 205 | r = redis.Redis(connection_pool=pool) 206 | r.set('foo', 'Bar') 207 | print r.get('foo') 208 | 209 | ``` 210 | 211 | #### 10.如果redis中的某个列表中的数据量非常大,如何实现循环显示每一个值? 212 | 213 | ``` 214 |      def list_iter(key, count=3): 215 | start = 0 216 | while True: 217 | result = conn.lrange(key, start, start+count-1) 218 | start += count 219 | if not result: 220 | break 221 | for item in result: 222 | yield item 223 |     # 调用 224 | for val in list_iter('num_list'): 225 | print(val) 226 | 227 | ``` 228 | 229 | #### 11.什么是一致性哈希?Python中是否有相应模块? 230 | 231 | 一致性hash算法(DHT)可以通过减少影响范围的方式,解决增减服务器导致的数据散列问题,从而解决了分布式环境下负载均衡问题; 232 | 如果存在热点数据,可以通过增添节点的方式,对热点区间进行划分,将压力分配至其他服务器,重新达到负载均衡的状态。 233 | 234 | Python模块--hash_ring,即Python中的一致性hash。 235 | 236 | 237 | #### 参考资料 238 | 239 | https://www.runoob.com/python/python-mysql.html 240 | 241 | https://www.cnblogs.com/wcwnina/p/10304641.html 242 | -------------------------------------------------------------------------------- /Python常用类库.md: -------------------------------------------------------------------------------- 1 | * [1.什么是时间元组?](#1什么是时间元组) 2 | * [2.使用datetime获取今天日期及前N天日期](#2使用datetime获取今天日期及前n天日期) 3 | * [3.获取以秒为单位的浮点时间time():](#3获取以秒为单位的浮点时间time) 4 | * [4.获取人可以直观理解的时间ctime():](#4获取人可以直观理解的时间ctime) 5 | * [5.浮点时间转化为直观时间:](#5浮点时间转化为直观时间) 6 | * [6.获取格林尼治时间UTC(Coordinated Universal Time,协调时间)格式:](#6获取格林尼治时间utccoordinated-universal-time协调时间格式) 7 | * [7.将UTC格式的时间转化为浮点值的时间:](#7将utc格式的时间转化为浮点值的时间) 8 | * [8.strptime 和 strftime 函数](#8strptime-和-strftime-函数) 9 | * [9.返回本地区当前日期时间datetime对象](#9返回本地区当前日期时间datetime对象) 10 | * [10.返回数组:(年、第多少周、星期几)](#10返回数组年第多少周星期几) 11 | * [11.如何用Python删除一个文件?](#11如何用python删除一个文件) 12 | * [12.python如何copy一个文件?](#12python如何copy一个文件) 13 | * [13.python如何打开文件?](#13python如何打开文件) 14 | * [14.python如何重命名文件?](#14python如何重命名文件) 15 | * [15.python如何创建目录?](#15python如何创建目录) 16 | * [16.python如何删除目录?](#16python如何删除目录) 17 | * [17.python如何进行文件定位?](#17python如何进行文件定位) 18 | * [18.python如何读取键盘输入?](#18python如何读取键盘输入) 19 | * [19.python如何关闭文件?](#19python如何关闭文件) 20 | * [20.python如何向文件写入数据?](#20python如何向文件写入数据) 21 | * [21.python如何从文件读取数据?](#21python如何从文件读取数据) 22 | 23 | 24 | ## 常用类库 25 | 26 | #### 1.什么是时间元组? 27 | 28 | 很多Python函数用一个元组装起来的9组数字处理时间: 29 | 30 | | 序号 | 字段 | 值 | 31 | | :--- | :----------- | :----------------------------------- | 32 | | 0 | 4位数年 | 2008 | 33 | | 1 | 月 | 1 到 12 | 34 | | 2 | 日 | 1到31 | 35 | | 3 | 小时 | 0到23 | 36 | | 4 | 分钟 | 0到59 | 37 | | 5 | 秒 | 0到61 (60或61 是闰秒) | 38 | | 6 | 一周的第几日 | 0到6 (0是周一) | 39 | | 7 | 一年的第几日 | 1到366 (儒略历) | 40 | | 8 | 夏令时 | -1, 0, 1, -1是决定是否为夏令时的旗帜 | 41 | 42 | 上述也就是struct_time元组。这种结构具有如下属性: 43 | 44 | | 序号 | 属性 | 值 | 45 | | :--- | :------- | :----------------------------------- | 46 | | 0 | tm_year | 2008 | 47 | | 1 | tm_mon | 1 到 12 | 48 | | 2 | tm_mday | 1 到 31 | 49 | | 3 | tm_hour | 0 到 23 | 50 | | 4 | tm_min | 0 到 59 | 51 | | 5 | tm_sec | 0 到 61 (60或61 是闰秒) | 52 | | 6 | tm_wday | 0到6 (0是周一) | 53 | | 7 | tm_yday | 1 到 366(儒略历) | 54 | | 8 | tm_isdst | -1, 0, 1, -1是决定是否为夏令时的旗帜 | 55 | 56 | #### 2.使用datetime获取今天日期及前N天日期 57 | 58 | 问:在Python中如何获取今天的日期?如何获取前N天的日期? 59 | 答:使用datetime模块可以完成日期获取任务。 60 | (1)获取当天日期 61 | 62 | ``` 63 | import datetime 64 | # 获取当天日期 65 | # strftime()函数是将time信息输出为想要的格式,如‘2020-08-03’ 66 | date_today = datetime.datetime.now().strftime('%Y-%m-%d') 67 | # 输出带有小时分钟的日期 68 | data_today2 = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S') 69 | 70 | ``` 71 | 72 | (2)获取前N天日期 73 | 74 | ``` 75 | # 通过timedelta(N)函数完成 76 | date_3today_ago = (datetime.datetime.now() - datetime.timedelta(3)).strftime('%Y-%m-%d') 77 | 78 | ``` 79 | 80 | #### 3.获取以秒为单位的浮点时间time(): 81 | 82 | ``` 83 | >>> import time 84 | >>> print time.time()#获取当前时间的浮点值,单位为秒 85 | 1369031293.33 86 | >>> 87 | ``` 88 | 89 | #### 4.获取人可以直观理解的时间ctime(): 90 | 91 | ``` 92 | print time.ctime() 93 | Mon May 20 14:29:30 2013#获取人能理解的直观时间 94 | ``` 95 | 96 | #### 5.浮点时间转化为直观时间: 97 | 98 | ``` 99 | >>> t = time.time()#浮点时间 100 | >>> print t 101 | 1369034676.69 102 | >>> print time.ctime(t)#浮点时间转化为直观时间 103 | Mon May 20 15:24:36 2013 104 | ``` 105 | 106 | #### 6.获取格林尼治时间UTC(Coordinated Universal Time,协调时间)格式: 107 | 108 | ``` 109 | >>> print time.gmtime()#获取UTC格式的当前时间 110 | time.struct_time(tm_year=2013, tm_mon=5, tm_mday=20, tm_hour=6, tm_min=37, tm_sec=45, tm_wday=0, tm_yday=140, tm_isdst=0) 111 | ``` 112 | 113 | 114 | 115 | #### 7.将UTC格式的时间转化为浮点值的时间: 116 | 117 | ``` 118 | >>> gmt = time.gmtime()#UTC格式的时间 119 | >>> print gmt 120 | time.struct_time(tm_year=2013, tm_mon=5, tm_mday=20, tm_hour=6, tm_min=48, tm_sec=13, tm_wday=0, tm_yday=140, tm_isdst=0) 121 | >>> print time.mktime(gmt)#将UTC格式的时间转化为浮点值的时间 122 | 1369003693.0 123 | 124 | >>> lt = time.localtime()#将UTC格式当前时区当前时间 125 | >>> print lt 126 | time.struct_time(tm_year=2013, tm_mon=5, tm_mday=20, tm_hour=14, tm_min=49, tm_sec=25, tm_wday=0, tm_yday=140, tm_isdst=0) 127 | >>> print time.mktime(lt)##将UTC格式的时间转化为浮点值的时间 128 | 1369032565.0 129 | ``` 130 | 131 | 132 | 133 | #### 8.strptime 和 strftime 函数 134 | 135 | ``` 136 | 时间.strftime(时间格式) 137 | datetime.strptime(字符串,时间格式) 138 | 139 | 示范: 140 | datetime.strptime(str,'%Y-%m-%d') 141 | datetime.now().strftime("%Y-%m-%d %H:%M:%S")  142 | ``` 143 | 144 | ### 145 | 146 | #### 9.返回本地区当前日期时间`datetime`对象 147 | 148 | ``` 149 | datetime.today() 150 | # 输出 : datetime.datetime(2019, 12, 9, 13, 27, 54, 693978) 151 | ``` 152 | 153 | #### 10.返回数组:(年、第多少周、星期几) 154 | 155 | ``` 156 | d = datetime(2019,12,6,13,30,50) 157 | d.isocalendar() 158 | # 输出 : (2019, 49, 5) 159 | ``` 160 | 161 | #### 11.如何用Python删除一个文件? 162 | 163 | 使用os.remove(filename)或者os.unlink(filename) 164 | 165 | #### 12.python如何copy一个文件? 166 | 167 | shutil模块有一个copyfile函数可以实现文件拷贝 168 | 169 | #### 13.python如何打开文件? 170 | 171 | open(file_name) 172 | 173 | #### 14.python如何重命名文件? 174 | 175 | os.rename(current_file_name, new_file_name) 176 | 177 | #### 15.python如何创建目录? 178 | 179 | os.mkdir("newdir") 180 | 181 | #### 16.python如何删除目录? 182 | 183 | os.rmdir('dirname') 184 | 185 | #### 17.python如何进行文件定位? 186 | 187 | tell()方法告诉你文件内的当前位置, 换句话说,下一次的读写会发生在文件开头这么多字节之后。 188 | 189 | seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。 190 | 191 | 如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。 192 | 193 | #### 18.python如何读取键盘输入? 194 | 195 | raw_input函数 196 | raw_input([prompt]) 函数从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符)。 197 | 198 | input函数 199 | input([prompt]) 函数和 raw_input([prompt]) 函数基本类似,但是 input 可以接收一个Python表达式作为输入,并将运算结果返回。 200 | 201 | #### 19.python如何关闭文件? 202 | 203 | File 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。 204 | 205 | 当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。 206 | 207 | #### 20.python如何向文件写入数据? 208 | 209 | File 对象的write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。 210 | 211 | write()方法不会在字符串的结尾添加换行符('\n'): 212 | 213 | #### 21.python如何从文件读取数据? 214 | 215 | File 对象的read())方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。 216 | 217 | 218 | 219 | #### 参考链接 220 | 221 | https://blog.csdn.net/LI20132017/article/details/107769363 222 | 223 | https://www.cnblogs.com/fengff/p/8674681.html 224 | 225 | https://blog.csdn.net/weixin_33853794/article/details/86739039 226 | 227 | https://www.runoob.com/python/python-tutorial.html 228 | -------------------------------------------------------------------------------- /PythonWeb开发.md: -------------------------------------------------------------------------------- 1 | * [1.什么是Flask?有什么优点?](#1什么是flask有什么优点) 2 | * [2.Django和Flask有什么区别?](#2django和flask有什么区别) 3 | * [3.Flask-WTF是什么,有什么特点?](#3flask-wtf是什么有什么特点) 4 | * [4.Flask脚本的常用方式是什么?](#4flask脚本的常用方式是什么) 5 | * [5.如何在Flask中访问会话?](#5如何在flask中访问会话) 6 | * [6.解释Python Flask中的数据库连接?](#6解释python-flask中的数据库连接) 7 | * [7.Flask框架有哪些依赖组件?](#7flask框架有哪些依赖组件) 8 | * [8.Flask蓝图的作用?](#8flask蓝图的作用) 9 | * [9.列举使用过的Flask第三方组件?](#9列举使用过的flask第三方组件) 10 | * [10. 简述Flask上下文管理流程?](#10-简述flask上下文管理流程) 11 | * [11.Flask框架默认session处理机制?](#11flask框架默认session处理机制) 12 | * [12.django请求的生命周期?](#12django请求的生命周期) 13 | * [13.列举django中间件的5个方法?以及django中间件的应用场景?](#13列举django中间件的5个方法以及django中间件的应用场景) 14 | * [14.django rest framework框架中都有那些组件?](#14django-rest-framework框架中都有那些组件) 15 | * [15.django rest framework如何实现的用户访问频率控制?](#15django-rest-framework如何实现的用户访问频率控制) 16 | * [16.django中如何实现单元测试?](#16django中如何实现单元测试) 17 | * [17.django-debug-toolbar的作用?](#17django-debug-toolbar的作用) 18 | * [18.什么是wsgi?](#18什么是wsgi) 19 | * [19.简述什么是FBV和CBV?](#19简述什么是fbv和cbv) 20 | * [20.django中csrf的实现机制](#20django中csrf的实现机制) 21 | * [21.Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别)](#21django本身提供了runserver为什么不能用来部署runserver与uwsgi的区别) 22 | * [22.Django如何实现websocket?](#22django如何实现websocket) 23 | 24 | #### 1.什么是Flask?有什么优点? 25 | 26 | Flask是一个Web框架,就是提供一个工具,库和技术来允许你构建一个Web应用程序。这个Web应用程序可以是一些Web页面,博客,wiki,基于Web的日里应用或商业网站。 27 | 28 | Flask属于微框架(micro-framework)这一类别,微架构通常是很小的不依赖外部库的框架。其优点如下: 29 | 30 | - 框架很轻量 31 | - 更新时依赖小 32 | - 专注于安全方面的bug 33 | 34 | #### 2.Django和Flask有什么区别? 35 | 36 | Flask 37 | 轻量级web框架,默认依赖两个外部库:jinja2和Werkzeug WSGI工具 38 | 适用于做小型网站以及web服务的API,开发大型网站无压力,但架构需要自己设计 39 | 与关系型数据库的结合不弱于Django,而与非关系型数据库的结合远远优于Django 40 | 41 | Django 42 | 重量级web框架,功能齐全,提供一站式解决的思路,能让开发者不用在选择上花费大量时间。 43 | 自带ORM(Object-Relational Mapping 对象关系映射)和模板引擎,支持jinja等非官方模板引擎。 44 | 自带ORM使Django和关系型数据库耦合度高,如果要使用非关系型数据库,需要使用第三方库 45 | 自带数据库管理app 46 | 成熟,稳定,开发效率高,相对于Flask,Django的整体封闭性比较好,适合做企业级网站的开发。 47 | python web框架的先驱,第三方库丰富 48 | 49 | 50 | #### 3.Flask-WTF是什么,有什么特点? 51 | 52 | Flask-wtf是一个用于表单处理、校验并提供CSRF验证的功能的扩展库 53 | Flask-wtf能把正表单免受CSRF<跨站请求伪造>的攻击 54 | 55 | #### 4.Flask脚本的常用方式是什么? 56 | 57 | 在shell中运行脚本文件 58 | 在python编译器中run 59 | 60 | #### 5.如何在Flask中访问会话? 61 | 62 | 会话(seesion)会话数据存储在服务器上。 会话是客户端登录到服务器并注销的时间间隔。 需要在此会话中进行的数据存储在服务器上的临时目录中。 63 | from flask import session导入会话对象 64 | session['name'] = 'admin'给会话添加变量 65 | session.pop('username', None)删除会话的变量 66 | 67 | 68 | #### 6.解释Python Flask中的数据库连接? 69 | 70 | python中的数据库连接有2种方式 71 | 1)在脚本中以用第三方库正常连接,用sql语句正常操作数据库,如mysql关系型数据库的pymsql库 72 | 2)用ORM来进行数据库连接,flask中典型的flask_sqlalchemy,已面向对象的方式进行数据库的连接与操作 73 | 74 | #### 7.Flask框架有哪些依赖组件? 75 | 76 | Route(路由) 77 | templates(模板) 78 | Models(orm模型) 79 | blueprint(蓝图) 80 | Jinja2模板引擎 81 | 82 | #### 8.Flask蓝图的作用? 83 | 84 | 蓝图Blueprint实现模块化的应用 85 | 86 | - book_bp = Blueprint('book', __name__)创建蓝图对象 87 | - 蓝图中使用路由@book_bp.route('url') 88 | - 在另一.py文件里导入和注册蓝图from book import book_bp app.register_blueprint(book_bp) 89 | 90 | 作用 91 | 将不同的功能模块化 92 | 构建大型应用 93 | 优化项目结构 94 | 增强可读性,易于维护(跟Django的view功能相似) 95 | 96 | 97 | #### 9.列举使用过的Flask第三方组件? 98 | 99 | flask_bootstrap 100 | flask-WTF 101 | flask_sqlalchemy 102 | 103 | #### 10. 简述Flask上下文管理流程? 104 | 105 | 每次有请求过来的时候,flask 会先创建当前线程或者进程需要处理的两个重要上下文对象,把它们保存到隔离的栈里面,这样视图函数进行处理的时候就能直接从栈上获取这些信息。 106 | 107 | #### 11.Flask框架默认session处理机制? 108 | 109 | Flask的默认session利用了Werkzeug的SecureCookie,把信息做序列化(pickle)后编码(base64),放到cookie里了。 110 | 111 | 过期时间是通过cookie的过期时间实现的。 112 | 113 | 为了防止cookie内容被篡改,session会自动打上一个叫session的hash串,这个串是经过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。 114 | 115 | #### 12.django请求的生命周期? 116 | 117 | 1.wsgi,请求封装后交给web框架 118 | 2.中间件,对请求进行校验或者在请求对象中添加其他相关数据, 119 | 3.路由匹配,根据浏览器发送的不同url去匹配不同的视图函数 120 | 4.视图函数,在视图函数中进行业务逻辑的处理 121 | 5.中间件,对响应的数据进行处理 122 | 6.wsgi,将响应的内容发送给浏览器 123 | 124 | #### 13.列举django中间件的5个方法?以及django中间件的应用场景? 125 | 126 | 1.process_request 127 | 接收到客户端信息后立即执行,视图函数之前 128 | 2.process_response 129 | 返回到客户端信息前最后执行,视图函数之后 130 | 3.process_view 131 | 拿到视图函数的名称,参数,执行process_view()方法 132 | 4.process_exception 133 | 视图函数出错时执行 134 | 5.process_template_response 135 | 在视图函数执行完后立即执行,前提是视图返回的对象中有一个render()方法 136 | 137 | #### 14.django rest framework框架中都有那些组件? 138 | 139 | 1.序列化组件:serializers 对queryset序列化以及对请求数据格式校验 140 | 2.路由组件routers 进行路由分发 141 | 3.视图组件ModelViewSet 帮助开发者提供了一些类,并在类中提供了多个方法 142 | 4.认证组件 写一个类并注册到认证类(authentication_classes),在类的的authticate方法中编写认证逻 143 | 5.权限组件 写一个类并注册到权限类(permission_classes),在类的的has_permission方法中编写认证逻辑。 144 | 6.频率限制 写一个类并注册到频率类(throttle_classes),在类的的allow_request/wait 方法中编写认证逻辑 145 | 7.解析器 选择对数据解析的类,在解析器类中注册(parser_classes) 146 | 8.渲染器 定义数据如何渲染到到页面上,在渲染器类中注册(renderer_classes) 147 | 9.分页 对获取到的数据进行分页处理, pagination_class 148 | 10.版本 版本控制用来在不同的客户端使用不同的行为 149 | 在url中设置version参数,用户请求时候传入参数。在request.version中获取版本,根据版本不同 做不同处理 150 | 151 | #### 15.django rest framework如何实现的用户访问频率控制? 152 | 153 | from rest_framework.throttling import SimpleRateThrottle 154 | 155 | 这里使用的节流类是继承了SimplePateThrottle类,而这个类利用了django内置的缓存来存储访问记录。通过全局节流设置,所有的视图类默认是使用UserThrottle类进行节流,如果不想使用默认的类就自定义给throttle_classes属性变量赋值,如:“throttle_classes = [VisitThrottle,]”。 156 | 157 | #### 16.django中如何实现单元测试? 158 | 159 | django的单元测试使用python的unittest模块,这个模块使用基于类的方法来定义测试。 160 | 161 | #### 17.django-debug-toolbar的作用? 162 | 163 | 用来调试请求的接口 164 | 165 | #### 18.什么是wsgi? 166 | 167 | WSGI是Python在处理HTTP请求时,规定的一种处理方式。如一个HTTP Request过来了,那么就有一个相应的处理函数来进行处理和返回结果。WSGI就是规定这个处理函数的参数长啥样的,它的返回结果是长啥样的?至于该处理函数的名子和处理逻辑是啥样的,那无所谓。简单而言,WSGI就是规定了处理函数的输入和输出格式。 168 | 169 | #### 19.简述什么是FBV和CBV? 170 | 171 | FBV和CBV本质是一样的,基于函数的视图叫做FBV,基于类的视图叫做CBV。 172 | 在python中使用CBV的优点: 173 | 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)。 174 | 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性。 175 | 176 | 177 | #### 20.django中csrf的实现机制 178 | 179 | 第一步:django第一次响应来自某个客户端的请求时,后端随机产生一个token值,把这个token保存在SESSION状态中;同时,后端把这个token放到cookie中交给前端页面; 180 | 第二步:下次前端需要发起请求(比如发帖)的时候把这个token值加入到请求数据或者头信息中,一起传给后端;Cookies:{csrftoken:xxxxx} 181 | 第三步:后端校验前端请求带过来的token和SESSION里的token是否一致。 182 | 183 | #### 21.Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别) 184 | 185 | 1)runserver方法是调试 Django 时经常用到的运行方式,它使用Django自带的 186 | WSGI Server 运行,主要在测试和开发中使用,并且 runserver 开启的方式也是单进程 。 187 | 2)uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http 等协议。注意uwsgi是一种通信协议,而uWSGI是实现uwsgi协议和WSGI协议的 Web 服务器。uWSGI具有超快的性能、低内存占用和多app管理等优点,并且搭配着Nginx就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署 。相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。 188 | 189 | #### 22.Django如何实现websocket? 190 | 191 | django实现websocket官方推荐大家使用channels。channels通过升级http协议来升级到websocket协议。保证实时通讯。也就是说,我们完全可以用channels实现我们的即时通讯。而不是使用长轮询和计时器方式来保证伪实时通讯。他通过改造django框架,使django既支持http协议又支持websocket协议。 192 | 193 | 194 | 195 | #### 参考资料 196 | 197 | https://blog.csdn.net/wl_python/article/details/81131873 198 | 199 | https://www.cnblogs.com/bk770466199/p/12696103.html 200 | 201 | https://www.jianshu.com/p/724233387ba3 202 | -------------------------------------------------------------------------------- /Python面向对象.md: -------------------------------------------------------------------------------- 1 | * [1.面向对象](#1面向对象) 2 | * [2.什么是类和类变量?](#2什么是类和类变量) 3 | * [3.实例和实例化以及实例变量](#3实例和实例化以及实例变量) 4 | * [4.数据成员](#4数据成员) 5 | * [5.方法和静态方法以及类方法](#5方法和静态方法以及类方法) 6 | * [6.什么是方法重写](#6什么是方法重写) 7 | * [7. _ _ init _ _](#7-_-_-init-_-_) 8 | * [8.self](#8self) 9 | * [9.类的初始化:new() 和 init()](#9类的初始化new-和-init) 10 | * [10.@classmethon](#10classmethon) 11 | * [11.@staticmethod](#11staticmethod) 12 | * [12.设计的一个面向对象程序设计的完整示例。](#12设计的一个面向对象程序设计的完整示例) 13 | * [13.私有属性](#13私有属性) 14 | * [14.类的继承](#14类的继承) 15 | * [15.多继承](#15多继承) 16 | 17 | 18 | #### 1.面向对象 19 | 20 | **抽象**:提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对类进行实例化得到对象。 21 | 22 | **封装**:封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等) 23 | 24 | **继承**:对现有类的一种复用机制。一个类如果继承现有的类,则这个类将拥有被继承类的所有非私有特性(属性和操作)。这里指的继承包含:类的继承和接口的实现。 25 | 26 | **多态**:多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多态特性。多态可以分成编译时多态和运行时多态。 27 | 28 | #### 2.什么是类和类变量? 29 | 30 | 用来描述具有相同属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。其中的对象被称作类的实例。 31 | 32 | 类变量:类变量是所有实例公有的变量。类变量定义在类中,但在方法体之外。 33 | 34 | #### 3.实例和实例化以及实例变量 35 | 36 | 实例:也称对象。通过类定义的初始化方法,赋予具体的值,成为一个”有血有肉的实体”。 37 | 38 | 实例化:创建类的实例的过程或操作。 39 | 40 | 实例变量:定义在实例中的变量,只作用于当前实例。 41 | 42 | #### 4.数据成员 43 | 44 | 类变量、实例变量、方法、类方法、静态方法和属性等的统称。 45 | 46 | #### 5.方法和静态方法以及类方法 47 | 48 | 方法:类中定义的函数。 49 | 50 | 静态方法:不需要实例化就可以由类执行的方法 51 | 52 | 类方法:类方法是将类本身作为对象进行操作的方法。 53 | 54 | #### 6.什么是方法重写 55 | 56 | 如果从父类继承的方法不能满足子类的需求,可以对父类的方法进行改写,这个过程也称override。 57 | 58 | #### 7. _ _ __init__ _ _ 59 | 60 | 可以成为类的实例对象的构造函数,每次通过类创建一个该类的对象是调用此函数,所以其下的以sefl.前缀的变量是每个创建好了的实例(化)对象的所独有的。换句话说,有多少个类的对象内存里就有多少份这个实例对象变量存在。就像生产了多少小汽车就有多少个方向盘似的。 61 | 62 | #### 8.self 63 | 64 | 代表运行时的类的实例对象本身,一般在类的内部设计时出现,在程序里使用对象编程时不用self。在实例对象的成员函数里以self.前缀的变量是实例对象的成员变量,没有self.的变量是本方法函数的局部变量。 65 | 66 | #### 9.类的初始化:new() 和 init() 67 | 68 | new()方法用来实例化最终的类对象,在类创建之前被调用,它在类的主体被执行完后开始执行。 69 | 70 | init()方法是在类被创建之后被调用,用来执行其他的一些输出化工作 71 | 72 | 当我们构造元类的时候,通常只需要定一个init()或new()方法,但不是两个都定义。但是,如果需要接受其他的关键词参数的话,这两个方法就要同时提供,并且都要提供对应的参数签名。 73 | 74 | #### 10.**@classmethon** 75 | 76 | 这个关键字是修饰器,修饰也是说下面的函数是类的方法函数而不是类的对象的方法函数。 77 | 78 | #### 11.**@staticmethod** 79 | 80 | 这个也是修饰器,说明接下来的函数是一个静态函数,和实例对象的成员函数、类函数的区别主要在第一个形参,既无self又无cls。可以被类或对象直接调用。 差不多解释完了,下面来看一个具体的类的实例程序。 81 | 82 | #### 12.设计的一个面向对象程序设计的完整示例。 83 | 84 | ``` 85 | # coding:utf-8 86 | class Horse(object): 87 | variety = "大宛马" 88 | def __init__(self, name = "green", height = 0.5, length = 1.3, sex = "male"): 89 | # self.name是成员变量,name是形参、局部变量 90 | self.name = name 91 | self.height = height 92 | self.length = length 93 | self.sex = sex 94 | print "A baby horse is born called", self.name 95 | 96 | def print_info(self): 97 | print self.name, self.height, self.length, self.sex, Horse.variety#,Horse.address 98 | Horse.print_variety() # 在对象方法里通过类调用类方法,避免 99 | Horse().print_ci(200, 100)# 对象调用静态方法 100 | Horse.print_ci(200, 100) # 类调用静态方法 101 | 102 | @staticmethod 103 | def print_ci(x, y): 104 | print x, y 105 | 106 | @classmethod 107 | def pp(cls): 108 | # 类使用类变量 109 | print cls.variety, Horse.variety, cls.address 110 | #cls.print_variety() 111 | print Horse().name # 对象使用对象的成员变量 112 | @classmethod 113 | def print_variety(cls): 114 | cls.address = "xi'an" 115 | print "type", type(cls.address) 116 | print cls.variety, Horse.variety, cls.address 117 | Horse.pp()# 类调用类方法 118 | Horse().print_ci(100, 100)# 对象调用静态方法 119 | 120 | a = Horse("xiaoxuanfeng") 121 | b = Horse("pilihuo", sex = "female") 122 | a.print_info() 123 | b.print_info() 124 | Horse.print_variety() 125 | print "*" * 20 126 | Horse.pp() # 类调用类方法 127 | Horse.print_ci(12, 23)# 类外类调用静态方法 128 | a.print_ci(23, 31) # 类外对象调用静态方法 129 | ``` 130 | 131 | #### 13.私有属性 132 | 133 | 变量和函数 134 | 135 | - 定义私有变量 136 | 137 | ``` 138 | class aa(object): 139 | def __init__(self, w, v): 140 | self.x = w 141 | self.__y = v 142 | def p(self): 143 | print " x", self.x 144 | print "__y", self.__y 145 | ai = aa(12, 13) 146 | ai.p() 147 | ``` 148 | 149 | 程序的执行结果: 150 | 151 | ``` 152 | x 12 153 | __y 13 154 | ``` 155 | 156 | - 定义私有函数,不能在类的外部调用。 157 | 158 | ``` 159 | class aa(object): 160 | def __init__(self, w, v): 161 | self.x = w 162 | self.__y = v 163 | def p(self): 164 | print " x", self.x 165 | print "__y", self.__y 166 | self.__q() 167 | def __q(self): 168 | print "private method of class aa" 169 | ai = aa(12, 13) 170 | ai.p() 171 | #aa.__q() 172 | #ai.__q() 173 | #ai._aa__q() 174 | ``` 175 | 176 | 程序的执行结果: 177 | 178 | ``` 179 | x 12 180 | __y 13 181 | private method of class aa 182 | ``` 183 | 184 | `__q`函数是类aa的私有函数,可以在类内部使用,但不能在类之外使用。 185 | 186 | #### 14.类的继承 187 | 188 | 假如已经有几个类,而类与类之间有共同的变量属性和函数属性,那就可以把这几个变量属性和函数属性提取出来作为基类的属性。而特殊的变量属性和函数属性,则在本类中定义,这样只需要继承这个基类,就可以访问基类的变量属性和函数属性。可以提高代码的可扩展性。通过继承可以快速扩展和实现函数的多样性 189 | 190 | 举例: 191 | 192 | ``` 193 | class aa(object): 194 | def __init__(self, v): 195 | self.x = v 196 | self.__pa = 10 197 | def p(self): 198 | print "class aa's instance method" 199 | def info(self): 200 | print "info of aa instance" 201 | class cc(aa): 202 | def __init__(self, v): 203 | self.z = v 204 | self__pc = 10 205 | def p(self): 206 | print "class cc's instance method" 207 | a = aa(10) 208 | c = cc(30) 209 | a.p() 210 | a.info() 211 | c.p() 212 | c.info() 213 | ``` 214 | 215 | 程序执行结果: 216 | 217 | ``` 218 | class aa's instance method 219 | info of aa instance 220 | class cc's instance method 221 | info of aa instance 222 | ``` 223 | 224 | #### 15.多继承 225 | 226 | Python的类允许可以有多个父类,从左至右有顺序要求,这和后续搜索查找数据和函数有关系。 227 | 228 | ``` 229 | class 子类(父类1, 父类2, ...) 230 | ``` 231 | 232 | 多继承时子类的父类间和子类要满足人类的**伦理规则**。 233 | 234 | 举例: 235 | 236 | ``` 237 | class aa(object): 238 | def __init__(self, v): 239 | self.x = v 240 | def px(self): 241 | print self.x 242 | 243 | class bb(object): 244 | def __init__(self, v): 245 | self.y = v 246 | def py(self): 247 | print self.y 248 | 249 | class cc(aa, bb): 250 | def __init__(self, v, v1 = 100): 251 | print "cc" 252 | super(cc, self).__init__(v1) 253 | #aa.__init__(self, v1) 254 | #bb.__init__(self, v1) 255 | print "ccx" 256 | self.z = v 257 | def pz(self): 258 | print self.z 259 | 260 | a = aa(12) 261 | a.px() 262 | b = bb(13) 263 | b.py() 264 | c = cc(14) 265 | print dir(c) 266 | c.pz() 267 | ``` 268 | 269 | 程序的执行结果: 270 | 271 | ``` 272 | 12 273 | 13 274 | cc 275 | ccx 276 | ['__class__', ..., '__weakref__', 'px', 'py', 'pz', 'x', 'z'] 277 | 14 278 | ``` 279 | 280 | #### 参考链接 281 | 282 | https://blog.csdn.net/weixin_39628063/article/details/111455821 283 | 284 | http://liao.cpython.org/27classobject/ 285 | 286 | https://blog.csdn.net/weixin_35390379/article/details/112022047 287 | 288 | -------------------------------------------------------------------------------- /Python爬虫.md: -------------------------------------------------------------------------------- 1 | 2 | * [1.scrapy框架有哪几个组件/模块?](#1scrapy框架有哪几个组件模块) 3 | * [2.简单说一下scrapy工作流程。](#2简单说一下scrapy工作流程) 4 | * [3.scrapy指纹去重原理和scrappy-redis的去重原理?](#3scrapy指纹去重原理和scrappy-redis的去重原理) 5 | * [4.请简要介绍下scrapy框架。](#4请简要介绍下scrapy框架) 6 | * [5.为什么要使用scrapy框架?scrapy框架有哪些优点?](#5为什么要使用scrapy框架scrapy框架有哪些优点) 7 | * [6.scrapy如何实现分布式抓取?](#6scrapy如何实现分布式抓取) 8 | * [7.scrapy和requests的使用情况?](#7scrapy和requests的使用情况) 9 | * [8.爬虫使用多线程好?还是多进程好?为什么?](#8爬虫使用多线程好还是多进程好为什么) 10 | * [9.了解哪些基于爬虫相关的模块?](#9了解哪些基于爬虫相关的模块) 11 | * [10.列举在爬虫过程中遇到的哪些比较难的反爬机制?](#10列举在爬虫过程中遇到的哪些比较难的反爬机制) 12 | * [11.简述如何抓取动态加载数据?](#11简述如何抓取动态加载数据) 13 | * [12.移动端数据如何抓取?](#12移动端数据如何抓取) 14 | * [13.如何实现全站数据爬取?](#13如何实现全站数据爬取) 15 | * [14.如何提升爬取数据的效率?](#14如何提升爬取数据的效率) 16 | * [15.列举你接触的反爬机制?](#15列举你接触的反爬机制) 17 | * [16.什么是深度优先和广度优先(优劣)](#16什么是深度优先和广度优先优劣) 18 | * [17.是否了解谷歌的无头浏览器?](#17是否了解谷歌的无头浏览器) 19 | * [18.说下Scrapy的优缺点。](#18说下scrapy的优缺点) 20 | * [19.需要登录的网页,如何解决同时限制ip,cookie,session?](#19需要登录的网页如何解决同时限制ipcookiesession) 21 | * [20.验证码的解决?](#20验证码的解决) 22 | * [21.滑动验证码如何破解?](#21滑动验证码如何破解) 23 | * [22.爬下来的数据是怎么存储?](#22爬下来的数据是怎么存储) 24 | * [23.cookie过期的处理问题?](#23cookie过期的处理问题) 25 | * [24.谈一谈你对Selenium和PhantomJS了解](#24谈一谈你对selenium和phantomjs了解) 26 | * [25.怎么判断网站是否更新?](#25怎么判断网站是否更新) 27 | 28 | 29 | #### 1.scrapy框架有哪几个组件/模块? 30 | 31 | Scrapy Engine: 这是引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等等!(像不像人的身体?) 32 | 33 | Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照一定的方式进行整理排列,入队、并等待Scrapy Engine(引擎)来请求时,交给引擎。 34 | 35 | Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理, 36 | 37 | Spiders:它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器), 38 | 39 | Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,比如去重,持久化存储(存数据库,写入文件,总之就是保存数据用的) 40 | 41 | Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件 42 | 43 | #### 2.简单说一下scrapy工作流程。 44 | 45 | 数据在整个Scrapy的流向: 46 | 47 | 程序运行的时候, 48 | 49 | 引擎:Hi!Spider, 你要处理哪一个网站? 50 | 51 | Spiders:我要处理23wx.com 52 | 53 | 引擎:你把第一个需要的处理的URL给我吧。 54 | 55 | Spiders:给你第一个URL是XXXXXXX.com 56 | 57 | 引擎:Hi!调度器,我这有request你帮我排序入队一下。 58 | 59 | 调度器:好的,正在处理你等一下。 60 | 61 | 引擎:Hi!调度器,把你处理好的request给我, 62 | 63 | 调度器:给你,这是我处理好的request 64 | 65 | 引擎:Hi!下载器,你按照下载中间件的设置帮我下载一下这个request 66 | 67 | 下载器:好的!给你,这是下载好的东西。(如果失败:不好意思,这个request下载失败,然后引擎告诉调度器,这个request下载失败了,你记录一下,我们待会儿再下载。) 68 | 69 | 引擎:Hi!Spiders,这是下载好的东西,并且已经按照Spider中间件处理过了,你处理一下(注意!这儿responses默认是交给def parse这个函数处理的) 70 | 71 | Spiders:(处理完毕数据之后对于需要跟进的URL),Hi!引擎,这是我需要跟进的URL,将它的responses交给函数 def xxxx(self, responses)处理。还有这是我获取到的Item。 72 | 73 | 引擎:Hi !Item Pipeline 我这儿有个item你帮我处理一下!调度器!这是我需要的URL你帮我处理下。然后从第四步开始循环,直到获取到你需要的信息, 74 | 75 | 注意!只有当调度器中不存在任何request了,整个程序才会停止,(也就是说,对于下载失败的URL,Scrapy会重新下载。) 76 | 77 | #### 3.scrapy指纹去重原理和scrappy-redis的去重原理? 78 | 79 | scrapy的去重原理流程:利用hash值和集合去重。首先创建fingerprint = set()结合,然后将request对象利用sha1对象进行信息摘要,摘要完成之后, 判断hash值是否在集合中,如果在,返回true,如果不在,就add到集合。 80 | 81 | scrapy-redis 的去重原理基本是一样的,只不过持久化存储到redis共享数据库中,当请求数据达到10亿级以上,这个时候就会非常消耗内存,一个sha1 40个字节,就会占40G的内存,这个存储绝大部分的数据库无法承受,这个时候就要使用布隆过滤器。 82 | 83 | #### 4.请简要介绍下scrapy框架。 84 | 85 | scrapy 是一个快速(fast)、高层次(high-level)的基于 python 的 web 爬虫构架,用于抓取web站点并从页面中提取结构化的数据。scrapy 使用了 Twisted异步网络库来处理网络通讯。 86 | 87 | #### 5.为什么要使用scrapy框架?scrapy框架有哪些优点? 88 | 89 | 它更容易构建大规模的抓取项目 90 | 它异步处理请求,速度非常快 91 | 它可以使用自动调节机制自动调整爬行速度 92 | 93 | #### 6.scrapy如何实现分布式抓取? 94 | 95 | 可以借助scrapy_redis类库来实现。 96 | 97 | 在分布式爬取时,会有master机器和slave机器,其中,master为核心服务器,slave为具体的爬虫服务器。 98 | 99 | 我们在master服务器上搭建一个redis数据库,并将要抓取的url存放到redis数据库中,所有的slave爬虫服务器在抓取的时候从redis数据库中去链接,由于scrapy_redis自身的队列机制,slave获取的url不会相互冲突,然后抓取的结果最后都存储到数据库中。master的redis数据库中还会将抓取过的url的指纹存储起来,用来去重。相关代码在dupefilter.py文件中的request_seen()方法中可以找到。 100 | 101 | 去重问题: 102 | dupefilter.py 里面的源码: 103 | def request_seen(self, request): 104 | fp = request_fingerprint(request) 105 | added = self.server.sadd(self.key, fp) 106 | return not added 107 | 去重是把 request 的 fingerprint 存在 redis 上,来实现的。 108 | 109 | #### 7.scrapy和requests的使用情况? 110 | 111 | requests 是 polling 方式的,会被网络阻塞,不适合爬取大量数据 112 | 113 | scapy 底层是异步框架 twisted ,并发是最大优势 114 | 115 | #### 8.爬虫使用多线程好?还是多进程好?为什么? 116 | 117 | 对于IO密集型代码(文件处理,网络爬虫),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,会造成不必要的时间等待,而开启多线程后,A线程等待时,会自动切换到线程B,可以不浪费CPU的资源,从而提升程序执行效率)。 118 | 119 | 在实际的采集过程中,既考虑网速和相应的问题,也需要考虑自身机器硬件的情况,来设置多进程或者多线程。 120 | 121 | #### 9.了解哪些基于爬虫相关的模块? 122 | 123 | 网络请求:urllib,requests,aiohttp 124 | 数据解析:re,xpath,bs4,pyquery 125 | selenium 126 | js逆向:pyexcJs 127 | 128 | #### 10.列举在爬虫过程中遇到的哪些比较难的反爬机制? 129 | 130 | 动态加载的数据 131 | 动态变化的请求参数 132 | js加密 133 | 代理 134 | cookie 135 | 136 | #### 11.简述如何抓取动态加载数据? 137 | 138 | 基于抓包工具进行全局搜索 139 | 如果动态加载的数据是密文,则全局搜索是搜索不到 140 | 141 | #### 12.移动端数据如何抓取? 142 | 143 | fiddler,appnium,网络配置 144 | 145 | #### 13.如何实现全站数据爬取? 146 | 147 | 基于手动请求发送+递归解析 148 | 基于CrwalSpider(LinkExtractor,Rule) 149 | 150 | #### 14.如何提升爬取数据的效率? 151 | 152 | 使用框架 153 | 线程池,多任务的异步协程 154 | 分布式 155 | 156 | #### 15.列举你接触的反爬机制? 157 | 158 | 从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分。这里我们只讨论数据采集部分。 159 | 160 | 一般网站从三个方面反爬虫:用户请求的Headers,用户行为,网站目录和数据加载方式。前两种比较容易遇到,大多数网站都从这些角度来反爬虫。第三种一些应用ajax的网站会采用,这样增大了爬取的难度。 161 | 162 | 1)通过Headers反爬虫 163 | 164 | 从用户请求的Headers反爬虫是最常见的反爬虫策略。很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer)。如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。对于检测Headers的反爬虫,在爬虫中修改或者添加Headers就能很好的绕过。 165 | 166 | 2)基于用户行为反爬虫 167 | 168 | 还有一部分网站是通过检测用户行为,例如同一IP短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。 169 | 170 | 大多数网站都是前一种情况,对于这种情况,使用IP代理就可以解决。可以专门写一个爬虫,爬取网上公开的代理ip,检测后全部保存起来。这样的代理ip爬虫经常会用到,最好自己准备一个。有了大量代理ip后可以每请求几次更换一个ip,这在requests或者urllib2中很容易做到,这样就能很容易的绕过第一种反爬虫。 171 | 172 | 对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。有些有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。 173 | 174 | 3)动态页面的反爬虫 175 | 176 | 上述的几种情况大多都是出现在静态页面,还有一部分网站,我们需要爬取的数据是通过ajax请求得到,或者通过JavaScript生成的。首先用Firebug或者HttpFox对网络请求进行分析。如果能够找到ajax请求,也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,直接利用requests或者urllib2模拟ajax请求,对响应的json进行分析得到需要的数据。 177 | 178 | 能够直接模拟ajax请求获取数据固然是极好的,但是有些网站把ajax请求的所有参数全部加密了。我们根本没办法构造自己所需要的数据的请求。我这几天爬的那个网站就是这样,除了加密ajax参数,它还把一些基本的功能都封装了,全部都是在调用自己的接口,而接口参数都是加密的。遇到这样的网站,我们就不能用上面的方法了,我用的是selenium+phantomJS框架,调用浏览器内核,并利用phantomJS执行js来模拟人为操作以及触发页面中的js脚本。从填写表单到点击按钮再到滚动页面,全部都可以模拟,不考虑具体的请求和响应过程,只是完完整整的把人浏览页面获取数据的过程模拟一遍。 179 | 180 | 用这套框架几乎能绕过大多数的反爬虫,因为它不是在伪装成浏览器来获取数据(上述的通过添加 Headers一定程度上就是为了伪装成浏览器),它本身就是浏览器,phantomJS就是一个没有界面的浏览器,只是操控这个浏览器的不是人。利用 selenium+phantomJS能干很多事情,例如识别点触式(12306)或者滑动式的验证码,对页面表单进行暴力破解等等。它在自动化渗透中还 会大展身手,以后还会提到这个。 181 | 182 | 183 | 184 | #### 16.什么是深度优先和广度优先(优劣) 185 | 186 | 默认情况下scrapy是深度优先。 187 | 深度优先:占用空间大,但是运行速度快。 188 | 广度优先:占用空间少,运行速度慢 189 | 190 | #### 17.是否了解谷歌的无头浏览器? 191 | 192 | 无头浏览器即headless browser,是一种没有界面的浏览器。既然是浏览器那么浏览器该有的东西它都应该有,只是看不到界面而已。 193 | 194 | Python中selenium模块中的PhantomJS即为无界面浏览器(无头浏览器):是基于QtWebkit的无头浏览器。 195 | 196 | #### 18.说下Scrapy的优缺点。 197 | 198 | 优点: 199 | scrapy 是异步的 200 | 采取可读性更强的xpath代替正则 201 | 强大的统计和log系统 202 | 同时在不同的url上爬行 203 | 支持shell方式,方便独立调试 204 | 写middleware,方便写一些统一的过滤器 205 | 通过管道的方式存入数据库 206 | 207 | 缺点:基于python的爬虫框架,扩展性比较差 208 | 基于twisted框架,运行中的exception是不会干掉reactor,并且异步框架出错后是不会停掉其他任务的,数据出错后难以察觉。 209 | 210 | #### 19.需要登录的网页,如何解决同时限制ip,cookie,session? 211 | 212 | 解决限制IP可以使用代理IP地址池、服务器;不适用动态爬取的情况下可以使用反编译JS文件获取相应的文件,或者换用其它平台(比如手机端)看看是否可以获取相应的json文件。 213 | 214 | #### 20.验证码的解决? 215 | 216 | 1.输入式验证码 217 | 解决思路:这种是最简单的一种,只要识别出里面的内容,然后填入到输入框中即可。这种识别技术叫OCR,这里我们推荐使用Python的第三方库,tesserocr。对于没有什么背影影响的验证码,直接通过这个库来识别就可以。但是对于有嘈杂的背景的验证码这种,直接识别识别率会很低,遇到这种我们就得需要先处理一下图片,先对图片进行灰度化,然后再进行二值化,再去识别,这样识别率会大大提高。 218 | 219 | 验证码识别大概步骤: 220 | 转化成灰度图 221 | 去背景噪声 222 | 图片分割 223 | 224 | 2.滑动式验证码 225 | 解决思路:对于这种验证码就比较复杂一点,但也是有相应的办法。我们直接想到的就是模拟人去拖动验证码的行为,点击按钮,然后看到了缺口 的位置,最后把拼图拖到缺口位置处完成验证。 226 | 227 | 第一步:点击按钮。然后我们发现,在你没有点击按钮的时候那个缺口和拼图是没有出现的,点击后才出现,这为我们找到缺口的位置提供了灵感。 228 | 229 | 第二步:拖到缺口位置。我们知道拼图应该拖到缺口处,但是这个距离如果用数值来表示?通过我们第一步观察到的现象,我们可以找到缺口的位置。这里我们可以比较两张图的像素,设置一个基准值,如果某个位置的差值超过了基准值,那我们就找到了这两张图片不一样的位置,当然我们是从那块拼图的右侧开始并且从左到右,找到第一个不一样的位置时就结束,这是的位置应该是缺口的left,所以我们使用selenium拖到这个位置即可。这里还有个疑问就是如何能自动的保存这两张图?这里我们可以先找到这个标签,然后获取它的location和size,然后 top,bottom,left,right = location['y'] ,location['y']+size['height']+ location['x'] + size['width'] ,然后截图,最后抠图填入这四个位置就行。具体的使用可以查看selenium文档,点击按钮前抠张图,点击后再抠张图。最后拖动的时候要需要模拟人的行为,先加速然后减速。因为这种验证码有行为特征检测,人是不可能做到一直匀速的,否则它就判定为是机器在拖动,这样就无法通过验证了。 230 | 231 | 3.点击式的图文验证 和 图标选择 232 | 233 | 图文验证:通过文字提醒用户点击图中相同字的位置进行验证。 234 | 235 | 图标选择: 给出一组图片,按要求点击其中一张或者多张。借用万物识别的难度阻挡机器。 236 | 237 | 这两种原理相似,只不过是一个是给出文字,点击图片中的文字,一个是给出图片,点出内容相同的图片。 238 | 239 | 这两种没有特别好的方法,只能借助第三方识别接口来识别出相同的内容,推荐一个超级鹰,把验证码发过去,会返回相应的点击坐标。 240 | 241 | 然后再使用selenium模拟点击即可。具体怎么获取图片和上面方法一样。 242 | 243 | #### 21.滑动验证码如何破解? 244 | 245 | 破解核心思路: 246 | 1、如何确定滑块滑动的距离? 247 | 滑块滑动的距离,需要检测验证码图片的缺口位置 248 | 滑动距离 = 终点坐标 - 起点坐标 249 | 然后问题转化为我们需要屏幕截图,根据selenium中的position方法并进行一些坐标计算,获取我们需要的位置 250 | 251 | 2、坐标我们如何获取? 252 | 起点坐标: 253 | 每次运行程序,位置固定不变,滑块左边界离验证码图片左边界有6px的距离 254 | 终点坐标: 255 | 每次运行程序,位置会变,我们需要计算每次缺口的位置 256 | 怎么计算终点也就是缺口的位置? 257 | 先举个例子,比如我下面两个图片都是120x60的图片,一个是纯色的图片,一个是有一个蓝色线条的图片(蓝色线条位置我事先设定的是60px位置),我现在让你通过程序确定蓝色线条的位置,你怎么确定? 258 | 259 | 答案: 260 | 遍历所有像素点色值,找出色值不一样的点的位置来确定蓝色线条的位置 261 | 这句话该怎么理解?大家点开我下面的图片,是不是发现图片都是由一个一个像素点组成的,120×60的图片,对应的像素就是横轴有120个像素点,纵轴有60个像素点,我们需要遍历两个图片的坐标并对比色值,从(0,0)(0,1)......一直到(120,60),开始对比两个图片的色值,遇到色值不一样的,我们return返回该位置即可 262 | 263 | #### 22.爬下来的数据是怎么存储? 264 | 265 | 以json格式存储到文本文件 266 | 这是最简单,最方便,最使用的存储方式,json格式保证你在打开文件时,可以直观的检查所存储的数据,一条数据存储一行,这种方式适用于爬取数据量比较小的情况,后续的读取分析也是很方便的。 267 | 268 | 存储到excel 269 | 如果爬取的数据很容易被整理成表格的形式,那么存储到excel是一个比较不错的选择,打开excel后,对数据的观察更加方便,excel也可以做一些简单的操作,写excel可以使用xlwt这个库,读取excel可以使用xlrd,同方法1一样,存储到excel里的数据不宜过多,此外,如果你是多线程爬取,不可能用多线程去写excel,这是一个限制。 270 | 271 | 存储到sqlite 272 | sqlite无需安装,是零配置数据库,这一点相比于mysql要轻便太多了,语法方面,只要你会mysql,操作sqlite就没有问题。当爬虫数据量很大时,需要持久化存储,而你又懒得安装mysql时,sqlite绝对是最佳选择,不多呢,它不支持多进程读写,因此不适合多进程爬虫。 273 | 274 | 存储到mysql数据库 275 | mysql可以远程访问,而sqlite不可以,这意味着你可以将数据存储到远程服务器主机上,当数据量非常大时,自然要选择mysql而不是sqlite,但不论是mysql还是sqlite,存储数据前都要先建表,根据要抓取的数据结构和内容,定义字段,这是一个需要耐心和精力的事情。 276 | 277 | 存储到mongodb 278 | 我最喜欢no sql 数据库的一个原因就在于不需要像关系型数据库那样去定义表结构,因为定义表结构很麻烦啊,要确定字段的类型,varchar 类型数据还要定义长度,你定义的小了,数据太长就会截断。 279 | mongodb 以文档方式存储数据,你使用pymongo这个库,可以直接将数据以json格式写入mongodb, 即便是同一个collection,对数据的格式也是没有要求的,实在是太灵活了。 280 | 刚刚抓下来的数据,通常需要二次清洗才能使用,如果你用关系型数据库存储数据,第一次就需要定义好表结构,清洗以后,恐怕还需要定义个表结构,将清洗后的数据重新存储,这样过于繁琐,使用mongodb,免去了反复定义表结构的过程。 281 | 282 | 283 | #### 23.cookie过期的处理问题? 284 | 285 | 这时候就需要cookie自动的更新了。通常怎样自动更新cookie呢?这里会用到selenium。 286 | 步骤1、 采用selenium自动登录获取cookie,保存到文件; 287 | 步骤2、 读取cookie,比较cookie的有效期,若过期则再次执行步骤1; 288 | 步骤3、 在请求其他网页时,填入cookie,实现登录状态的保持。 289 | 290 | 291 | #### 24.谈一谈你对Selenium和PhantomJS了解 292 | 293 | selenium 294 | Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等主流浏览器。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。 295 | 296 | 它的功能有: 297 | 框架底层使用JavaScript模拟真实用户对浏览器进行操作。测试脚本执行时,浏览器自动按照脚本代码做出点击,输入,打开,验证等操作,就像真实用户所做的一样,从终端用户的角度测试应用程序。 298 | 使浏览器兼容性测试自动化成为可能,尽管在不同的浏览器上依然有细微的差别。 299 | 使用简单,可使用Java,Python等多种语言编写用例脚本 300 | 也就是说,它可以根据指令,做出像真实的人在访问浏览器一样的动作,比如打开网页,截图等功能。 301 | 302 | phantomjs 303 | (新版本的selenium已经开始弃用phantomjs, 不过有时候我们可以单独用它做一些事情) 304 | 305 | 是一个基于Webkit的无界面浏览器,可以把网站内容加载到内存中并执行页面上的各种脚本(比如js)。 306 | 307 | 308 | #### 25.怎么判断网站是否更新? 309 | 310 | 1、304页面http状态码 311 | 312 | 当第二次请求页面访问的时候,该页面如果未更新,则会反馈一个304代码,而搜索引擎也会利用这个304http状态码来进行判断页面是否更新。 313 | 314 | 首先第一次肯定是要爬取网页的,假设是A.html,这个网页存储在磁盘上,相应地有个修改时间(也即是更新这个文件的时间)。 315 | 316 | 那么第二次爬取的时候,如果发现这个网页本地已经有了,例如A.html,这个时候,你只需要向服务器发送一个If-Modified-Since的请求,把A.html的修改时间带上去。 317 | 318 | 如果这段时间内,A.html更新了,也就是A.html过期了,服务器就会HTTP状态码200,并且把新的文件发送过来,这时候只要更新A.html即可。 319 | 320 | 如果这段时间内,A.html的内容没有变,服务器就会返返回HTTP状态码304(不返回文件内容),这个时候就不需要更新文件。 321 | 322 | 2、Last-Modified文件最后修改时间 323 | 324 | 这是http头部信息中的一个属性,主要是记录页面最后一次的修改时间,往往我们会发现,一些权重很高的网站,及时页面内容不更新,但是快照却还是能够每日更新,这其中就有Last-Modified的作用。通产情况下,下载网页我们使用HTTP协议,向服务器发送HEAD请求,可以得到页面的最后修改时间LastModifed,或者标签ETag。将这两个变量和上次下载记录的值的比较就可以知道一个网页是否跟新。这个策略对于静态网页是有效的。是对于绝大多数动态网页如ASP,JSP来说,LastModifed就是服务器发送Response的时间,并非网页的最后跟新时间,而Etag通常为空值。所以对于动态网页使用LastModifed和Etag来判断是不合适的,因此Last-Modified只是蜘蛛判断页面是否更新的一个参考值,而不是条件。 325 | 326 | 327 | 328 | 329 | #### 参考资料 330 | 331 | https://blog.csdn.net/weixin_45387317/article/details/101375974 332 | 333 | https://www.cnblogs.com/tianyiliang/p/10219034.html 334 | 335 | https://www.sohu.com/a/340282079_120123190 336 | 337 | https://www.cnblogs.com/linglichong/p/12425560.html 338 | 339 | http://blog.itpub.net/69923331/viewspace-2654286/ 340 | 341 | https://www.cnblogs.com/cherish-cxh/p/12778718.html 342 | -------------------------------------------------------------------------------- /Python进阶.md: -------------------------------------------------------------------------------- 1 | * [1.写函数,接收两个数字参数,返回最大值](#1写函数接收两个数字参数返回最大值) 2 | * [2.写函数,获取传入列表的所有奇数位索引对应的元素,并将其作为新列表返回。](#2写函数获取传入列表的所有奇数位索引对应的元素并将其作为新列表返回) 3 | * [3.写函数,检查传入的字符串是否含有空字符串,返回结果,包含空字符串返回True,不包含返回False](#3写函数检查传入的字符串是否含有空字符串返回结果包含空字符串返回true不包含返回false) 4 | * [4.定义一个函数,实现两个数四则运算,要注意有3个参数,分别是运算符和两个运算的数字.](#4定义一个函数实现两个数四则运算要注意有3个参数分别是运算符和两个运算的数字) 5 | * [5.filter、map、reduce 的作用?](#5filtermapreduce-的作用) 6 | * [6.请实现一个装饰器,通过一次调用使函数重复执行5次。](#6请实现一个装饰器通过一次调用使函数重复执行5次) 7 | * [7.如何判断一个值是函数还是方法?](#7如何判断一个值是函数还是方法) 8 | * [8.可更改(mutable)与不可更改(immutable)对象](#8可更改mutable与不可更改immutable对象) 9 | * [9.匿名函数](#9匿名函数) 10 | * [10.变量作用域](#10变量作用域) 11 | * [11.模块与包](#11模块与包) 12 | * [12.模块的使用](#12模块的使用) 13 | * [13.包的使用](#13包的使用) 14 | * [14.File(文件)方法 python3](#14file文件方法--python3) 15 | * [open() 方法](#open-方法) 16 | * [15.异常处理的定义](#15异常处理的定义) 17 | * [16.异常处理的意义](#16异常处理的意义) 18 | * [17.常见的异常](#17常见的异常) 19 | * [18.如何进行异常处理](#18如何进行异常处理) 20 | 21 | #### 1.写函数,接收两个数字参数,返回最大值 22 | 23 | ``` 24 | def res_max(number1,number2): 25 | l1 = [] 26 | l1.append(number1) 27 | l1.append(number2) 28 | return max(l1) 29 | ``` 30 | 31 | #### 2.写函数,获取传入列表的所有奇数位索引对应的元素,并将其作为新列表返回。 32 | 33 | ``` 34 | def getnewlist(mylist): 35 |   list1=[]; 36 |   for i in range(0,len(mylist)): 37 |     if i%2!=0: 38 |     list1.append(mylist[i]) 39 |   return list1 40 | ``` 41 | 42 | #### 3.写函数,检查传入的字符串是否含有空字符串,返回结果,包含空字符串返回True,不包含返回False 43 | 44 | ``` 45 | def str_spack(string): 46 | if string.find(' '): 47 | return True 48 | else: 49 | return False 50 | ``` 51 | 52 | #### 4.定义一个函数,实现两个数四则运算,要注意有3个参数,分别是运算符和两个运算的数字. 53 | 54 | ``` 55 | def arithmetic(number1, number2, symbol): 56 | 57 | if symbol == '+': 58 | s = number1 + number2 59 | elif symbol == '-': 60 | s = number1 - number2 61 | elif symbol == '*': 62 | s = number1 * number2 63 | elif symbol == '/': 64 | s = number1 / number2 65 | return s 66 | 67 | 方法二: 68 | def getresult(num1,fh,num2): 69 | str1=str(num1)+fh+str(num2) 70 | return eval(str1) 71 | print(getresult(10,'*',20)) 72 | ``` 73 | 74 | #### 5.filter、map、reduce 的作用? 75 | 76 | 1. filter---过滤条件用的 77 | 2. map--将内容里的元素 逐个处理 78 | 3. reduce--用于做累计算的 79 | 80 | #### 6.请实现一个装饰器,通过一次调用使函数重复执行5次。 81 | 82 | ``` 83 | import time 84 | def wrapper(func): 85 | def inner(*args,**kwargs): 86 | for i in range(5): 87 | time.sleep(0.5) 88 | func(*args,**kwargs) 89 | return inner 90 | @wrapper 91 | def func(): 92 | print('a') 93 | 94 | func() 95 | ``` 96 | 97 | 98 | 99 | #### 7.如何判断一个值是函数还是方法? 100 | 101 | 用type()来判断,如果是method为方法,如果是function则是函数。 102 | 103 | 括号中写入变量名,,不要有括号什么别的符号之类的 104 | 105 | #### 8.可更改(mutable)与不可更改(immutable)对象 106 | 107 | 在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。 108 | 109 | - **不可变类型:**变量赋值 **a=5** 后再赋值 **a=10**,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。 110 | - **可变类型:**变量赋值 **la=[1,2,3,4]** 后再赋值 **la[2]=5** 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。 111 | 112 | python 函数的参数传递: 113 | 114 | - **不可变类型:**类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。 115 | - **可变类型:**类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响 116 | 117 | python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。 118 | 119 | #### 9.匿名函数 120 | 121 | python 使用 lambda 来创建匿名函数。 122 | 123 | - lambda只是一个表达式,函数体比def简单很多。 124 | - lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。 125 | - lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。 126 | - 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。 127 | 128 | #### 10.变量作用域 129 | 130 | 一个程序的所有的变量并不是在哪个位置都可以访问的。访问权限决定于这个变量是在哪里赋值的。 131 | 132 | 变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。两种最基本的变量作用域如下: 133 | 134 | - 全局变量 135 | - 局部变量 136 | 137 | #### 11.模块与包 138 | 139 | 模块首先是一个含有源代码的文件在Python里以.py结尾,文件里可以有函数的定义、变量的定义或者对象(类的实例化)的定义等等内容。如果一个项目的代码量较大,函数较多,最好把一个文件分为多个文件来管理,这样总程序脉络清晰易于维护和团队分工协作,这就是Python里存在模块的意义所在。模块名就是文件名(不含.py),例如假设有一个模块:xopowo.py那么模块名为xopowo。 140 | 141 | 但当一个项目的模块文件不断的增多,为了更好地管理项目,通常将功能相近相关的模块放在同一个目录下,这就是包,故包从物理结构上看对应于一个目录,一个特殊要求,包目录下必有一个空的__init__.py文件,这是包区分普通目录的标签或者说是标志。包下可以又有包称为子包,子包也是一个目录,子包的目录下也得有一个空的__init__.py文件。这样就构成了分级或者说分层的项目管理体系。 142 | 143 | #### 12.模块的使用 144 | 145 | 模块,可是Python自带的、而外安装的或者开发者自己写的,在一个文件里使用模块很简单用import即可,import有点像C语言的include。 146 | 147 | 以Python2的内建模块[datetime](https://docs.python.org/2.7/library/datetime.html)为例,讲解一下模块的基本使用。 148 | 149 | 在新程序里使用datetime模块可以有两种方式:方式一是把模块引入,而模块里的函数的使用需要用点运算的方式来来使用。 150 | 151 | ``` 152 | import datetime 153 | birthday = datetime.date(2011,7,23) 154 | print birthday 155 | ``` 156 | 157 | 而文件引用模块里某函数还有另外一种方式就是用from import来直接引入某模块里的某函数,即方式二。 158 | 159 | ``` 160 | from datetime import date,time 161 | birthday = date(2011,7,23) 162 | print birthday 163 | ``` 164 | 165 | 使用方式二文件只能用import后列出的函数,而模块datetime里的其他函数无法在本文件里使用,所以一种特殊的写法如下: 166 | 167 | ``` 168 | from datetime import * 169 | ``` 170 | 171 | 也就是说datetime里的所有函数在本程序里均可使用。 172 | 173 | #### 13.包的使用 174 | 175 | 包,实际是更大规模的以目录形式存在的模块集合,包可以含子包,包区别于目录是包的目录下有一个空的__init__.py文件。包和模块一样有Python自带的包,也可以通过工具安装一些包,例如numpy就是数据科学领域比较常用的一个包,需额外安装,当然也可以自己开发一些包。 176 | 177 | 以Python2自带的包[multiprocessing](https://docs.python.org/2.7/library/multiprocessing.html)为例,其下还有子包[dummy](https://docs.python.org/2.7/library/multiprocessing.html#module-multiprocessing.dummy)。 178 | 179 | ``` 180 | liao@liao:/usr/lib/python2.7/multiprocessing$ ls 181 | connection.py forking.py heap.pyc managers.py pool.pyc queues.py reduction.pyc synchronize.py 182 | connection.pyc forking.pyc __init__.py managers.pyc process.py queues.pyc sharedctypes.py synchronize.pyc 183 | dummy heap.py __init__.pyc pool.py process.pyc reduction.py sharedctypes.pyc util.py 184 | liao@liao:/usr/lib/python2.7/multiprocessing$ ls dummy/ 185 | connection.py connection.pyc __init__.py __init__.pyc 186 | liao@liao:/usr/lib/python2.7/multiprocessing$ 187 | ``` 188 | 189 | multiprocess包下有很多的模块,例如process模块,那么可以在一个示例程序里使用包multiprocess里的process模块。 190 | 191 | ``` 192 | #coding:utf-8 193 | from multiprocessing import Process 194 | import os 195 | def test(name): 196 | print "Process ID: %s" % (os.getpid()) 197 | print "Parent Process ID: %s" % (os.getppid()) 198 | if __name__ == "__main__": 199 | proc = Process(target=test, args=('nmask',)) 200 | proc.start() 201 | proc.join() 202 | ``` 203 | 204 | 需要解释的是`from multiprocessing import Process`是从包multiprocess里引入Process, 但Process类定义在process.py文件里,包含Process类的process.py文件是在multiprocessing目录下的,故是multiprocessing包里的一个模块。通过Python交互环境可以查明这一点。 205 | 206 | ``` 207 | >>> from multiprocessing import Process 208 | >>> help(Process) 209 | Help on class Process in module multiprocessing.process: 210 | 211 | class Process(__builtin__.object) 212 | ``` 213 | 214 | 代码`from multiprocessing import Process`也可以这样去写`from multiprocessing.process import Process`这样写既写了包名又写了模块名即`包.模块`,其实在Python里一般还是直接用包名(偷懒),而少有既写包又写模块的。 215 | 216 | #### 14.File(文件)方法 python3 217 | 218 | ### open() 方法 219 | 220 | Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。 221 | 222 | **注意:**使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。 223 | 224 | open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)。 225 | 226 | ``` 227 | open(file, mode='r') 228 | ``` 229 | 230 | 完整的语法格式为: 231 | 232 | ``` 233 | open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 234 | ``` 235 | 236 | 参数说明: 237 | 238 | - file: 必需,文件路径(相对或者绝对路径)。 239 | - mode: 可选,文件打开模式 240 | - buffering: 设置缓冲 241 | - encoding: 一般使用utf8 242 | - errors: 报错级别 243 | - newline: 区分换行符 244 | - closefd: 传入的file参数类型 245 | - opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。 246 | 247 | #### 15.异常处理的定义 248 | 249 | python解释器检测到错误,触发异常(也允许程序员自己触发异常) 250 | 251 | 程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关) 252 | 253 | 如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理 254 | 255 | #### 16.异常处理的意义 256 | 257 | python解析器去执行程序,检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码不会运行,所以你必须提供一种异常处理机制来增强你程序的健壮性与容错性 258 | 259 | #### 17.常见的异常 260 | 261 | ``` 262 | AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x 263 | IOError 输入/输出异常;基本上是无法打开文件 264 | ImportError 无法引入模块或包;基本上是路径问题或名称错误 265 | IndentationError 语法错误(的子类) ;代码没有正确对齐 266 | IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] 267 | KeyError 试图访问字典里不存在的键 268 | KeyboardInterrupt Ctrl+C被按下 269 | NameError 尝试访问一个没有申明的变量 270 | SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了) 271 | TypeError 传入对象类型与要求的不符合 272 | UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它 273 | ValueError 传入一个调用者不期望的值,即使值的类型是正确的 274 | ``` 275 | 276 | #### 18.如何进行异常处理 277 | 278 | - 使用if判断式 279 | 280 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 281 | 282 | ``` 283 | num1=input('>>: ') #输入一个字符串试试 284 | if num1.isdigit(): 285 | int(num1) #我们的正统程序放到了这里,其余的都属于异常处理范畴 286 | elif num1.isspace(): 287 | print('输入的是空格,就执行我这里的逻辑') 288 | elif len(num1) == 0: 289 | print('输入的是空,就执行我这里的逻辑') 290 | else: 291 | print('其他情情况,执行我这里的逻辑') 292 | 293 | #第二段代码 294 | # num2=input('>>: ') #输入一个字符串试试 295 | # int(num2) 296 | 297 | #第三段代码 298 | # num3=input('>>: ') #输入一个字符串试试 299 | # int(num3) 300 | ``` 301 | 302 | 问题一: 303 | 使用if的方式我们只为第一段代码加上了异常处理,针对第二段代码,你得重新写一堆if,elif等 304 | 而这些if,跟你的代码逻辑并无关系,可读性差 305 | 306 | 问题二: 307 | 第一段代码和第二段代码实际上是同一种异常,都是ValueError,相同的错误按理说只处理一次就可以了,而用if,由于这二者if的条件不同,这只能逼着你重新写一个新的if来处理第二段代码的异常 308 | 第三段也一样 309 | 310 | - try...except 311 | 312 | 语法: 313 | 314 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 315 | 316 | ``` 317 | try: 318 | <语句> #运行别的代码 319 | except <异常类型>: 320 | <语句> #如果在try部份引发了'name'异常 321 | except <异常类型> as <数据>: 322 | <语句> #如果引发了'name'异常,获得附加的数据 323 | else: 324 | <语句> #如果没有异常发生 325 | ``` 326 | 327 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 328 | 329 | 330 | 331 | 注: 332 | 333 | python2 和 3 处理 except 子句的语法有点不同,需要注意; 334 | 335 |         Python2 336 | 337 | ``` 338 | try: 339 | print (1/0) 340 | except ZeroDivisionError, err:      # , 加原因参数名称 341 | print ('Exception: ', err) 342 | ``` 343 | 344 |         Python3 345 | 346 | ``` 347 | try: 348 | print (1/0) 349 | except ZeroDivisionError as err: # as 加原因参数名称 350 | print ('Exception: ', err) 351 | ``` 352 | 353 | 例 354 | 355 | ``` 356 | try: 357 | fh = open("testfile", "w") 358 | fh.write("这是一个测试文件,用于测试异常!!") 359 | except IOError: 360 | print("Error: 没有找到文件或读取文件失败") 361 | else: 362 | print("内容写入文件成功") 363 | fh.close() 364 | ``` 365 | 366 | 367 | 368 | 输出 369 | 370 | ``` 371 | 内容写入文件成功 372 | ``` 373 | 374 | 注: 375 | 376 | 异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。(**异常是由程序的错误引起的,语法上的错误跟异常处理无关,必须在程序运行前就修正)** 377 | 378 | ``` 379 | # 未捕获到异常,程序直接报错 380 | 381 | s1 = 'hello' 382 | try: 383 | int(s1) 384 | except IndexError as e: 385 | print e 386 | ``` 387 | 388 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 389 | 390 | 输出 391 | 392 | ``` 393 | File "/Users/hexin/PycharmProjects/py3/day9/1.py", line 11 394 | print e 395 | ^ 396 | SyntaxError: Missing parentheses in call to 'print' 397 | ``` 398 | 399 | 400 | 401 | - 多分支 402 | 403 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 404 | 405 | ``` 406 | try: 407 | msg=input('>>:') 408 | int(msg) #ValueError 409 | # 410 | # print(x) #NameError 411 | # # 412 | # # l=[1,2] 413 | # # l[10] #IndexError 414 | # 415 | # 1+'asdfsadfasdf' #TypeError 416 | 417 | except ValueError as e: 418 | print(e) 419 | except NameError: 420 | print('NameError') 421 | except KeyError as e: 422 | print(e) 423 | ``` 424 | 425 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 426 | 427 | ``` 428 | >>:gg 429 | invalid literal for int() with base 10: 'gg' 430 | ``` 431 | 432 | 433 | 434 | - 万能异常 435 | 436 | 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常 437 | 438 | ``` 439 | s1 = 'hello' 440 | try: 441 | int(s1) 442 | except Exception as e: 443 | '丢弃或者执行其他逻辑' 444 | print(e) 445 | ``` 446 | 447 | 输出 448 | 449 | ``` 450 | invalid literal for int() with base 10: 'hello' 451 | ``` 452 | 453 | 454 | 455 | - try-finally 语句 456 | 457 | try-finally 语句无论是否发生异常都将执行最后的代码。 458 | 459 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 460 | 461 | ``` 462 | s1 = 'hello' 463 | try: 464 | int(s1) 465 | except IndexError as e: 466 | print(e) 467 | except KeyError as e: 468 | print(e) 469 | except ValueError as e: 470 | print(e) 471 | #except Exception as e: 472 | # print(e) 473 | else: 474 | print('try内代码块没有异常则执行我') 475 | finally: 476 | print('无论异常与否,都会执行该模块,通常是进行清理工作') 477 | ``` 478 | 479 | ![复制代码](https://common.cnblogs.com/images/copycode.gif) 480 | 481 | 输出 482 | 483 | ``` 484 | invalid literal for int() with base 10: 'hello' 485 | 无论异常与否,都会执行该模块,通常是进行清理工作 486 | ``` 487 | 488 | 489 | 490 | - raise主动触发异常 491 | 492 | 我们可以使用raise语句自己触发异常 493 | 494 | raise语法格式如下: 495 | 496 | ``` 497 | raise [Exception [, args [, traceback]]] 498 | ``` 499 | 500 | 语句中Exception是异常的类型(例如,NameError)参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。 501 | 502 | 最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。 503 | 504 | ``` 505 | try: 506 | raise TypeError('类型错误') 507 | except Exception as e: 508 | print(e) 509 | ``` 510 | 511 | 输出 512 | 513 | ``` 514 | 类型错误 515 | ``` 516 | 517 | 518 | 519 | - 自定义异常 520 | 521 | ``` 522 | class hexinException(BaseException): 523 | def __init__(self,msg): 524 | self.msg=msg 525 | def __str__(self): 526 | return self.msg 527 | 528 | try: 529 | raise hexinException('类型错误') 530 | except hexinException as e: 531 | print(e) 532 | ``` 533 | 534 | 535 | 536 | 输出 537 | 538 | ``` 539 | 类型错误 540 | ``` 541 | 542 | 543 | 544 | 545 | #### 参考链接 546 | 547 | https://www.cnblogs.com/puti306/p/12080526.html 548 | 549 | https://www.cnblogs.com/jiazeng/articles/11299438.html 550 | 551 | https://www.runoob.com/python/python-functions.html 552 | 553 | https://www.runoob.com/python/python-files-io.html 554 | 555 | https://www.cnblogs.com/zhangyingai/p/7097920.html 556 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 这个Repo主要用来分享Python面试题,目前已经涵盖Python基础、Python面向对象、Python进阶、Python爬虫、Python Web开发、Python数据库编程等内容,后续还会不断更新。 3 | 4 | 如果对于有所帮助,可以给个star。有纰漏的地方,欢迎给我们提PR。 5 | 6 | 如果想获取本Repo的PDF版本,可以用微信扫描下方二维码,回复 “pdf” ,即可获取。 7 | 如果二维码加载不出来,可以在微信搜索公众号 “Python技术之家”,回复 “pdf” ,即可获取PDF版本。 8 | 9 | ![Python技术之家](https://gitee.com/PythonInterviewHub/PythonInterview/raw/main/imgs/Python%E6%8A%80%E6%9C%AF%E4%B9%8B%E5%AE%B6.jpg) 10 | 11 | 12 | 13 | ## Python基础 14 | * [1.为什么学习Python](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#1为什么学习python) 15 | * [2.Python和其他语言的区别](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#2python和其他语言的区别) 16 | * [3.Python的优势](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#3python的优势) 17 | * [4.Python的解释器种类?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#4python的解释器种类) 18 | * [5.python2和python3区别](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#5python2和python3区别) 19 | * [6.深拷贝和浅拷贝的区别是什么?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#6深拷贝和浅拷贝的区别是什么) 20 | * [7.位和字节的关系?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#7位和字节的关系) 21 | * [8.b、B、KB、MB、GB 的关系?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#8bbkbmbgb-的关系) 22 | * [9.python递归的最大层数?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#9python递归的最大层数) 23 | * [10.解释 Python 中的 help() 函数和 dir() 函数。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#10解释-python-中的-help-函数和-dir-函数) 24 | * [11.当退出 Python 时是否释放所有内存分配?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#11当退出-python-时是否释放所有内存分配) 25 | * [12.什么是 Python 字典?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#12什么是-python-字典) 26 | * [13.能否解释一下 *args 和 **kwargs?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#13能否解释一下-args-和-kwargs) 27 | * [14.什么是负索引?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#14什么是负索引) 28 | * [15. 如何随机打乱列表中元素,要求不引用额外的内存空间?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#15-如何随机打乱列表中元素要求不引用额外的内存空间) 29 | * [16.解释 Python 中的 join() 和 split() 函数](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#16解释-python-中的-join-和-split-函数) 30 | * [17.Python 区分大小写吗?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#17python-区分大小写吗) 31 | * [18.Python 中标识符的命名规则?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#18python-中标识符的命名规则) 32 | * [19.如何删除字符串中的前置空格](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#19如何删除字符串中的前置空格) 33 | * [20.Python 中的 pass 语句有什么作用?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#20python-中的-pass-语句有什么作用) 34 | * [21.请解释 Python 中的闭包?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#21请解释-python-中的闭包) 35 | * [22.解释 Python 中的//,%和**运算符](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#22解释-python-中的和运算符) 36 | * [23.Python 中有多少种运算符,解释算术运算符。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#23python-中有多少种运算符解释算术运算符) 37 | * [24.解释 Python 中的关系运算符。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#24解释-python-中的关系运算符) 38 | * [25.解释 Python 中的位运算符](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#25解释-python-中的位运算符) 39 | * [26.如何在 Python 使用多进制数字?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#26如何在-python-使用多进制数字) 40 | * [27.如何获取字典中的所有键?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#27如何获取字典中的所有键) 41 | * [28.问什么标识符不建议使用下划线开头?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#28问什么标识符不建议使用下划线开头) 42 | * [29.什么是元组的解封装?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#29什么是元组的解封装) 43 | * [30.Python3和Python2中 int 和 long的区别?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#30python3和python2中-int-和-long的区别) 44 | * [31.列举 Python 中的基本数据类型?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#31列举-python-中的基本数据类型) 45 | * [32.将"hello world"转换为首字母大写"Hello World](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#32将hello-world转换为首字母大写hello-world) 46 | * [33.如何检测字符串中只含有数字?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#33如何检测字符串中只含有数字) 47 | * [34.将字符串"ilovechina"进行反转](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#34将字符串ilovechina进行反转) 48 | * [35.Python 交换两个变量的值](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#35python-交换两个变量的值) 49 | * [36.Python 里面如何实现 tuple 和 list 的转换?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#36python-里面如何实现-tuple-和-list-的转换) 50 | * [37.Python 中的字符串格式化方式你知道哪些?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#37python-中的字符串格式化方式你知道哪些) 51 | * [38.如何对list去重?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#38如何对list去重) 52 | * [39.给定两个 list,A 和 B,找出相同元素和不同元素](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#39给定两个-lista-和-b找出相同元素和不同元素) 53 | * [40.如何打乱一个列表的元素?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#40如何打乱一个列表的元素) 54 | * [41.字典操作中 del 和 pop 有什么区别](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#41字典操作中-del-和-pop-有什么区别) 55 | * [42.请合并下面两个字典 a = {“A”:1,“B”:2},b = {“C”:3,“D”:4}](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#42请合并下面两个字典-a--a1b2b--c3d4) 56 | * [43.如何把元组 (“a”,“b”) 和元组 (1,2),变为字典 {“a”:1,“b”:2}](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#43如何把元组-ab-和元组-12变为字典-a1b2) 57 | * [44.如何交换字典 {“A”:1,“B”:2}的键和值](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#44如何交换字典-a1b2的键和值) 58 | * [45.切片Slice](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#45切片slice) 59 | * [46.什么是切片](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#46什么是切片) 60 | * [47.元组的定义](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#47元组的定义) 61 | * [48.字符串的三种引号](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#48字符串的三种引号) 62 | * [49.字典dict访问](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#49字典dict访问) 63 | * [50.字典的setdefault函数](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python基础.md#50字典的setdefault函数) 64 | 65 | 66 | 67 | ## Python面向对象 68 | 69 | * [1.面向对象](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#1面向对象) 70 | * [2.什么是类和类变量?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#2什么是类和类变量) 71 | * [3.实例和实例化以及实例变量](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#3实例和实例化以及实例变量) 72 | * [4.数据成员](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#4数据成员) 73 | * [5.方法和静态方法以及类方法](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#5方法和静态方法以及类方法) 74 | * [6.什么是方法重写](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#6什么是方法重写) 75 | * [7. _ _ init _ _](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#7-_-_-init-_-_) 76 | * [8.self](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#8self) 77 | * [9.类的初始化:new() 和 init()](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#9类的初始化new-和-init) 78 | * [10.@classmethon](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#10classmethon) 79 | * [11.@staticmethod](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#11staticmethod) 80 | * [12.设计的一个面向对象程序设计的完整示例。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#12设计的一个面向对象程序设计的完整示例) 81 | * [13.私有属性](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#13私有属性) 82 | * [14.类的继承](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#14类的继承) 83 | * [15.多继承](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python面向对象.md#15多继承) 84 | 85 | ## Python常用类库 86 | * [1.什么是时间元组?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#1什么是时间元组) 87 | * [2.使用datetime获取今天日期及前N天日期](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#2使用datetime获取今天日期及前n天日期) 88 | * [3.获取以秒为单位的浮点时间time():](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#3获取以秒为单位的浮点时间time) 89 | * [4.获取人可以直观理解的时间ctime():](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#4获取人可以直观理解的时间ctime) 90 | * [5.浮点时间转化为直观时间:](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#5浮点时间转化为直观时间) 91 | * [6.获取格林尼治时间UTC(Coordinated Universal Time,协调时间)格式:](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#6获取格林尼治时间utccoordinated-universal-time协调时间格式) 92 | * [7.将UTC格式的时间转化为浮点值的时间:](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#7将utc格式的时间转化为浮点值的时间) 93 | * [8.strptime 和 strftime 函数](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#8strptime-和-strftime-函数) 94 | * [9.返回本地区当前日期时间datetime对象](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#9返回本地区当前日期时间datetime对象) 95 | * [10.返回数组:(年、第多少周、星期几)](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#10返回数组年第多少周星期几) 96 | * [11.如何用Python删除一个文件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#11如何用python删除一个文件) 97 | * [12.python如何copy一个文件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#12python如何copy一个文件) 98 | * [13.python如何打开文件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#13python如何打开文件) 99 | * [14.python如何重命名文件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#14python如何重命名文件) 100 | * [15.python如何创建目录?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#15python如何创建目录) 101 | * [16.python如何删除目录?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#16python如何删除目录) 102 | * [17.python如何进行文件定位?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#17python如何进行文件定位) 103 | * [18.python如何读取键盘输入?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#18python如何读取键盘输入) 104 | * [19.python如何关闭文件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#19python如何关闭文件) 105 | * [20.python如何向文件写入数据?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#20python如何向文件写入数据) 106 | * [21.python如何从文件读取数据?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python常用类库.md#21python如何从文件读取数据) 107 | 108 | ## Python进阶 109 | * [1.写函数,接收两个数字参数,返回最大值](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#1写函数接收两个数字参数返回最大值) 110 | * [2.写函数,获取传入列表的所有奇数位索引对应的元素,并将其作为新列表返回。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#2写函数获取传入列表的所有奇数位索引对应的元素并将其作为新列表返回) 111 | * [3.写函数,检查传入的字符串是否含有空字符串,返回结果,包含空字符串返回True,不包含返回False](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#3写函数检查传入的字符串是否含有空字符串返回结果包含空字符串返回true不包含返回false) 112 | * [4.定义一个函数,实现两个数四则运算,要注意有3个参数,分别是运算符和两个运算的数字.](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#4定义一个函数实现两个数四则运算要注意有3个参数分别是运算符和两个运算的数字) 113 | * [5.filter、map、reduce 的作用?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#5filtermapreduce-的作用) 114 | * [6.请实现一个装饰器,通过一次调用使函数重复执行5次。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#6请实现一个装饰器通过一次调用使函数重复执行5次) 115 | * [7.如何判断一个值是函数还是方法?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#7如何判断一个值是函数还是方法) 116 | * [8.可更改(mutable)与不可更改(immutable)对象](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#8可更改mutable与不可更改immutable对象) 117 | * [9.匿名函数](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#9匿名函数) 118 | * [10.变量作用域](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#10变量作用域) 119 | * [11.模块与包](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#11模块与包) 120 | * [12.模块的使用](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#12模块的使用) 121 | * [13.包的使用](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#13包的使用) 122 | * [14.File(文件)方法 python3](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#14file文件方法--python3) 123 | * [open() 方法](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#open-方法) 124 | * [15.异常处理的定义](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#15异常处理的定义) 125 | * [16.异常处理的意义](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#16异常处理的意义) 126 | * [17.常见的异常](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#17常见的异常) 127 | * [18.如何进行异常处理](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python进阶.md#18如何进行异常处理) 128 | 129 | ## PythonWeb开发 130 | * [1.什么是Flask?有什么优点?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#1什么是flask有什么优点) 131 | * [2.Django和Flask有什么区别?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#2django和flask有什么区别) 132 | * [3.Flask-WTF是什么,有什么特点?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#3flask-wtf是什么有什么特点) 133 | * [4.Flask脚本的常用方式是什么?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#4flask脚本的常用方式是什么) 134 | * [5.如何在Flask中访问会话?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#5如何在flask中访问会话) 135 | * [6.解释Python Flask中的数据库连接?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#6解释python-flask中的数据库连接) 136 | * [7.Flask框架有哪些依赖组件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#7flask框架有哪些依赖组件) 137 | * [8.Flask蓝图的作用?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#8flask蓝图的作用) 138 | * [9.列举使用过的Flask第三方组件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#9列举使用过的flask第三方组件) 139 | * [10. 简述Flask上下文管理流程?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#10-简述flask上下文管理流程) 140 | * [11.Flask框架默认session处理机制?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#11flask框架默认session处理机制) 141 | * [12.django请求的生命周期?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#12django请求的生命周期) 142 | * [13.列举django中间件的5个方法?以及django中间件的应用场景?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#13列举django中间件的5个方法以及django中间件的应用场景) 143 | * [14.django rest framework框架中都有那些组件?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#14django-rest-framework框架中都有那些组件) 144 | * [15.django rest framework如何实现的用户访问频率控制?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#15django-rest-framework如何实现的用户访问频率控制) 145 | * [16.django中如何实现单元测试?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#16django中如何实现单元测试) 146 | * [17.django-debug-toolbar的作用?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#17django-debug-toolbar的作用) 147 | * [18.什么是wsgi?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#18什么是wsgi) 148 | * [19.简述什么是FBV和CBV?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#19简述什么是fbv和cbv) 149 | * [20.django中csrf的实现机制](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#20django中csrf的实现机制) 150 | * [21.Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别)](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#21django本身提供了runserver为什么不能用来部署runserver与uwsgi的区别) 151 | * [22.Django如何实现websocket?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/PythonWeb开发.md#22django如何实现websocket) 152 | 153 | 154 | ## Python爬虫 155 | * [1.scrapy框架有哪几个组件/模块?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#1scrapy框架有哪几个组件模块) 156 | * [2.简单说一下scrapy工作流程。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#2简单说一下scrapy工作流程) 157 | * [3.scrapy指纹去重原理和scrappy-redis的去重原理?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#3scrapy指纹去重原理和scrappy-redis的去重原理) 158 | * [4.请简要介绍下scrapy框架。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#4请简要介绍下scrapy框架) 159 | * [5.为什么要使用scrapy框架?scrapy框架有哪些优点?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#5为什么要使用scrapy框架scrapy框架有哪些优点) 160 | * [6.scrapy如何实现分布式抓取?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#6scrapy如何实现分布式抓取) 161 | * [7.scrapy和requests的使用情况?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#7scrapy和requests的使用情况) 162 | * [8.爬虫使用多线程好?还是多进程好?为什么?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#8爬虫使用多线程好还是多进程好为什么) 163 | * [9.了解哪些基于爬虫相关的模块?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#9了解哪些基于爬虫相关的模块) 164 | * [10.列举在爬虫过程中遇到的哪些比较难的反爬机制?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#10列举在爬虫过程中遇到的哪些比较难的反爬机制) 165 | * [11.简述如何抓取动态加载数据?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#11简述如何抓取动态加载数据) 166 | * [12.移动端数据如何抓取?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#12移动端数据如何抓取) 167 | * [13.如何实现全站数据爬取?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#13如何实现全站数据爬取) 168 | * [14.如何提升爬取数据的效率?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#14如何提升爬取数据的效率) 169 | * [15.列举你接触的反爬机制?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#15列举你接触的反爬机制) 170 | * [16.什么是深度优先和广度优先(优劣)](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#16什么是深度优先和广度优先优劣) 171 | * [17.是否了解谷歌的无头浏览器?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#17是否了解谷歌的无头浏览器) 172 | * [18.说下Scrapy的优缺点。](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#18说下scrapy的优缺点) 173 | * [19.需要登录的网页,如何解决同时限制ip,cookie,session?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#19需要登录的网页如何解决同时限制ipcookiesession) 174 | * [20.验证码的解决?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#20验证码的解决) 175 | * [21.滑动验证码如何破解?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#21滑动验证码如何破解) 176 | * [22.爬下来的数据是怎么存储?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#22爬下来的数据是怎么存储) 177 | * [23.cookie过期的处理问题?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#23cookie过期的处理问题) 178 | * [24.谈一谈你对Selenium和PhantomJS了解](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#24谈一谈你对selenium和phantomjs了解) 179 | * [25.怎么判断网站是否更新?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python爬虫.md#25怎么判断网站是否更新) 180 | 181 | ## Python数据库编程 182 | 183 | * [1.什么是MySQLdb?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#1什么是mysqldb) 184 | * [2.如何连接数据库?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#2如何连接数据库) 185 | * [3.如何创建数据库表?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#3如何创建数据库表) 186 | * [4.如何执行数据插入?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#4如何执行数据插入) 187 | * [5.如何执行数据库查询操作?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#5如何执行数据库查询操作) 188 | * [6.如何更新数据库数据?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#6如何更新数据库数据) 189 | * [7.如何删除数据库数据?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#7如何删除数据库数据) 190 | * [8.如何使用数据库事务?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#8如何使用数据库事务) 191 | * [9.python如何操作redis?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#9python如何操作redis) 192 | * [10.如果redis中的某个列表中的数据量非常大,如何实现循环显示每一个值?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#10如果redis中的某个列表中的数据量非常大如何实现循环显示每一个值) 193 | * [11.什么是一致性哈希?Python中是否有相应模块?](https://github.com/PythonInterviewHub/PythonInterview/blob/main/Python数据库编程.md#11什么是一致性哈希python中是否有相应模块) 194 | -------------------------------------------------------------------------------- /Python基础.md: -------------------------------------------------------------------------------- 1 | * [1.为什么学习Python](#1为什么学习python) 2 | * [2.Python和其他语言的区别](#2python和其他语言的区别) 3 | * [从三个方面看Python](#从三个方面看python) 4 | * [语言特点](#语言特点) 5 | * [语言类型](#语言类型) 6 | * [第三方库](#第三方库) 7 | * [3.Python的优势](#3python的优势) 8 | * [4.Python的解释器种类?](#4python的解释器种类) 9 | * [5.python2和python3区别](#5python2和python3区别) 10 | * [6.深拷贝和浅拷贝的区别是什么?](#6深拷贝和浅拷贝的区别是什么) 11 | * [7.位和字节的关系?](#7位和字节的关系) 12 | * [8.b、B、KB、MB、GB 的关系?](#8bbkbmbgb-的关系) 13 | * [9.python递归的最大层数?](#9python递归的最大层数) 14 | * [10.解释 Python 中的 help() 函数和 dir() 函数。](#10解释-python-中的-help-函数和-dir-函数) 15 | * [11.当退出 Python 时是否释放所有内存分配?](#11当退出-python-时是否释放所有内存分配) 16 | * [12.什么是 Python 字典?](#12什么是-python-字典) 17 | * [13.*能否解释一下 *args 和 **kwargs?](#13能否解释一下-args-和-kwargs) 18 | * [14.什么是负索引?](#14什么是负索引) 19 | * [15. 如何随机打乱列表中元素,要求不引用额外的内存空间?](#15-如何随机打乱列表中元素要求不引用额外的内存空间) 20 | * [16.解释 Python 中的 join() 和 split() 函数](#16解释-python-中的-join-和-split-函数) 21 | * [17.Python 区分大小写吗?](#17python-区分大小写吗) 22 | * [18.Python 中标识符的命名规则?](#18python-中标识符的命名规则) 23 | * [19.如何删除字符串中的前置空格](#19如何删除字符串中的前置空格) 24 | * [20.Python 中的 pass 语句有什么作用?](#20python-中的-pass-语句有什么作用) 25 | * [21.请解释 Python 中的闭包?](#21请解释-python-中的闭包) 26 | * [22.解释 Python 中的//,%和**运算符](#22解释-python-中的和运算符) 27 | * [23.Python 中有多少种运算符,解释算术运算符。](#23python-中有多少种运算符解释算术运算符) 28 | * [24.解释 Python 中的关系运算符。](#24解释-python-中的关系运算符) 29 | * [25.解释 Python 中的位运算符](#25解释-python-中的位运算符) 30 | * [26.如何在 Python 使用多进制数字?](#26如何在-python-使用多进制数字) 31 | * [27.如何获取字典中的所有键?](#27如何获取字典中的所有键) 32 | * [28.问什么标识符不建议使用下划线开头?](#28问什么标识符不建议使用下划线开头) 33 | * [29.什么是元组的解封装?](#29什么是元组的解封装) 34 | * [30.Python3和Python2中 int 和 long的区别?](#30python3和python2中-int-和-long的区别) 35 | * [31.列举 Python 中的基本数据类型?](#31列举-python-中的基本数据类型) 36 | * [32.将"hello world"转换为首字母大写"Hello World](#32将hello-world转换为首字母大写hello-world) 37 | * [33.如何检测字符串中只含有数字?](#33如何检测字符串中只含有数字) 38 | * [34.将字符串"ilovechina"进行反转](#34将字符串ilovechina进行反转) 39 | * [35.Python 交换两个变量的值](#35python-交换两个变量的值) 40 | * [36.Python 里面如何实现 tuple 和 list 的转换?](#36python-里面如何实现-tuple-和-list-的转换) 41 | * [37.Python 中的字符串格式化方式你知道哪些?](#37python-中的字符串格式化方式你知道哪些) 42 | * [38.如何对list去重?](#38如何对list去重) 43 | * [39.给定两个 list,A 和 B,找出相同元素和不同元素](#39给定两个-lista-和-b找出相同元素和不同元素) 44 | * [40.如何打乱一个列表的元素?](#40如何打乱一个列表的元素) 45 | * [41.字典操作中 del 和 pop 有什么区别](#41字典操作中-del-和-pop-有什么区别) 46 | * [42.请合并下面两个字典 a = {“A”:1,“B”:2},b = {“C”:3,“D”:4}](#42请合并下面两个字典-a--a1b2b--c3d4) 47 | * [43.如何把元组 (“a”,“b”) 和元组 (1,2),变为字典 {“a”:1,“b”:2}](#43如何把元组-ab-和元组-12变为字典-a1b2) 48 | * [44.如何交换字典 {“A”:1,“B”:2}的键和值](#44如何交换字典-a1b2的键和值) 49 | * [45.切片Slice](#45切片slice) 50 | * [46.什么是切片](#46什么是切片) 51 | * [step = 1](#step--1) 52 | * [step > 1](#step--1-1) 53 | * [47.元组的定义](#47元组的定义) 54 | * [48.字符串的三种引号](#48字符串的三种引号) 55 | * [49.字典dict访问](#49字典dict访问) 56 | * [50.字典的setdefault函数](#50字典的setdefault函数) 57 | 58 | #### 1.为什么学习Python 59 | 60 | 因为自己本身想学习编程,在同学和朋友的推荐下,我最后选择了Python。 61 | 62 | Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数据分析这方面。在未来我觉得是往自动化,人工智能这方面发展的,所以学习了Python。 63 | 64 | #### 2.Python和其他语言的区别 65 | 66 | ### 从三个方面看Python 67 | 68 | - #### 语言特点 69 | 70 | > 简洁 优雅 省略了各种大括号和分号,还有一些关键字,类型说明 71 | 72 | - #### 语言类型 73 | 74 | > 解释型语言,运行的时候是一行一行的解释,并运行,所以调试代码很方便,开发效率高. 75 | 76 | - #### 第三方库 77 | 78 | > python是开源的,并且python的定位时任由其发展,应用领域很多 79 | > 比如Web,运维,自动化测试,爬虫,数据分析,人工智能.Python具有非常完备的 80 | > 第三方库 81 | 82 | #### 3.Python的优势 83 | 84 | 1. 简单:Python奉行简洁主义,易于读写,它使你能够专注于解决问题而不是去搞明白语言本身。 85 | 2. 免费:Python是开源软件。这意味着你不用花一分钱便能复制、阅读、改动它,这也是Python越来越优秀的原因——它是由一群希望看到一个更加优秀的Python的人创造并经常改进着的。 86 | 3. 兼容性:Python兼容众多平台,所以开发者不会遇到使用其他语言时常会遇到的困扰。 87 | 4. 面向对象:Python既支持面向过程,也支持面向对象编程。在面向过程编程中,程序员复用代码,在面向对象编程中,使用基于数据和函数的对象。 88 | 5. 丰富的库:Python标准库确实很庞大。它可以帮助你处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。 89 | 6. 规范的代码:Python采用强制缩进的方式使得代码具有极佳的可读性。 90 | 7. 可扩展性和可嵌入性。如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能。 91 | 92 | #### 4.Python的解释器种类? 93 | 94 | 95 | 96 | Python解释器主要有以下几个: 97 | 98 | 1、CPython 99 | 100 | 官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器。CPython是使用最广且被的Python解释器。 101 | 102 | 2、IPython 103 | IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。 104 | 105 | 3、PyPy 106 | 107 | PyPy是另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。 108 | 绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。如果你的代码要放到PyPy下执行,就需要了解PyPy和CPython的不同点。 109 | 110 | 4、Jython 111 | 112 | Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。 113 | 114 | 5、IronPython 115 | 116 | IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。 117 | 118 | 在这些Python解释器中,使用广泛的是CPython 。 119 | 120 | #### 5.python2和python3区别 121 | 122 | 一、核心类差异 123 | 124 | 1. Python3 对 Unicode 字符的原生支持。 125 | Python2 中使用 ASCII 码作为默认编码方式导致 string 有两种类型 str 和 unicode,Python3 只 126 | 支持 unicode 的 string。Python2 和 Python3 字节和字符对应关系为: 127 | 2. Python3 采用的是绝对路径的方式进行 import 128 | Python2 中相对路径的 import 会导致标准库导入变得困难(想象一下,同一目录下有 file.py,如 129 | 何同时导入这个文件和标准库 file)。Python3 中这一点将被修改,如果还需要导入同一目录的文件必 130 | 须使用绝对路径,否则只能使用相关导入的方式来进行导入。 131 | 3. Python2 中存在老式类和新式类的区别,Python3 统一采用新式类。新式类声明要求继承 object, 132 | 必须用新式类应用多重继承。 133 | 4. Python3 使用更加严格的缩进。Python2 的缩进机制中,1 个 tab 和 8 个 space 是等价的,所 134 | 以在缩进中可以同时允许 tab 和 space 在代码中共存。这种等价机制会导致部分 IDE 使用存在问题。 135 | Python3 中 1 个 tab 只能找另外一个 tab 替代,因此 tab 和 space 共存会导致报错:TabError: 136 | inconsistent use of tabs and spaces in indentation. 137 | 138 | 139 | 二、废弃类差异 140 | 141 | 1. print 语句被 Python3 废弃,统一使用 print 函数 142 | 2. exec 语句被 python3 废弃,统一使用 exec 函数 143 | 3. execfile 语句被 Python3 废弃,推荐使用 exec(open("./filename").read()) 144 | 4. 不相等操作符"<>"被 Python3 废弃,统一使用"!=" 145 | 5. long 整数类型被 Python3 废弃,统一使用 int 146 | 6. xrange 函数被 Python3 废弃,统一使用 range,Python3 中 range 的机制也进行修改并提高 147 | 了大数据集生成效率 148 | 7. Python3 中这些方法再不再返回 list 对象:dictionary 关联的 keys()、values()、items(),zip(), 149 | map(),filter(),但是可以通过 list 强行转换: 150 | 8. mydict={"a":1,"b":2,"c":3} 151 | 9. mydict.keys() # 152 | 10. list(mydict.keys()) #['a', 'c', 'b'] 153 | 11. 迭代器 iterator 的 next()函数被 Python3 废弃,统一使用 next(iterator) 154 | 12. raw_input 函数被 Python3 废弃,统一使用 input 函数 155 | 13. 字典变量的 has_key 函数被 Python 废弃,统一使用 in 关键词 156 | 14. file 函数被 Python3 废弃,统一使用 open 来处理文件,可以通过 io.IOBase 检查文件类型 157 | 15. apply 函数被 Python3 废弃 158 | 16. 异常 StandardError 被 Python3 废弃,统一使用 Exception 159 | 160 | 161 | 三 、修改类差异 162 | 163 | 1. 浮点数除法操作符“/”和“//”的区别 164 | “ / ”: 165 | Python2:若为两个整形数进行运算,结果为整形,但若两个数中有一个为浮点数,则结果为 166 | 浮点数; 167 | Python3:为真除法,运算结果不再根据参加运算的数的类型。 168 | “//”: 169 | Python2:返回小于除法运算结果的最大整数;从类型上讲,与"/"运算符返回类型逻辑一致。 170 | Python3:和 Python2 运算结果一样。 171 | 2. 异常抛出和捕捉机制区别 172 | Python2 173 | 3. raise IOError, "file error" #抛出异常 174 | 4. except NameError, err: #捕捉异常 175 | Python3 176 | 5. raise IOError("file error") #抛出异常 177 | 6. except NameError as err: #捕捉异常 178 | 7. for 循环中变量值区别 179 | Python2,for 循环会修改外部相同名称变量的值 180 | 8. i = 1 181 | 9. print ('comprehension: ', [i for i in range(5)]) 182 | 10. print ('after: i =', i ) #i=4 183 | Python3,for 循环不会修改外部相同名称变量的值 184 | 11. i = 1 185 | 12. print ('comprehension: ', [i for i in range(5)]) 186 | 13. print ('after: i =', i ) #i=1 187 | 14. round 函数返回值区别 188 | Python2,round 函数返回 float 类型值 189 | 15. isinstance(round(15.5),int) #True 190 | Python3,round 函数返回 int 类型值 191 | 16. isinstance(round(15.5),float) #True 192 | 17. 比较操作符区别 193 | Python2 中任意两个对象都可以比较 194 | 18. 11 < 'test' #True 195 | Python3 中只有同一数据类型的对象可以比较 196 | 19. 11 < 'test' # TypeError: unorderable types: int() < str() 197 | 198 | 四、第三方工具包差异 199 | 五、工具安装问题 200 | 201 | 202 | 203 | #### 6.深拷贝和浅拷贝的区别是什么? 204 | 205 | 深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。 206 | 假设B复制了A,修改A的时候,看B是否发生变化: 207 | 如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值) 208 | 如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同值) 209 | 210 | 浅拷贝(shallowCopy)只是增加了一指针指向已存在的内存地址。 211 | 深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存 212 | 213 | 使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。 214 | 215 | 浅拷贝:仅仅时指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。 216 | 深拷贝:在计算机中开辟一块新的内存地址用于存放复制的对象。 217 | 218 | 但是在python中,对浅拷贝和深拷贝,还需要分数据类型是可变类型还是不可边类型。 219 | 可变数据类型 不可变数据类型 220 | ![image-20210309150501258](C:\Users\qq\AppData\Roaming\Typora\typora-user-images\image-20210309150501258.png) 221 | 222 | #### 7.位和字节的关系? 223 | 224 | 位:``"位(bit)"``是电子计算机中最小的数据单位。每一位的状态只能是``0``或``1``。 225 | 226 | 字节:``8``个二进制位构成``1``个``"字节(Byte)"``,它是存储空间的基本计量单位。``1``个字节可以储存``1``个英文字母或者半个汉字,换句话说,``1``个汉字占据``2``个字节的存储空间。 227 | 228 | 229 | 230 | #### 8.b、B、KB、MB、GB 的关系? 231 | 232 | ``` 233 | b 比特bit ``/` `位 234 | B——字节 ``1` `B ``=` `8b``(``8``个bit``/` `位)一个字节(byte)等于``8``位(bit) 235 | KB——千比特 ``1` `kB ``=` `1024` `B (kB ``-` `kilobajt) 236 | MB——兆比特 ``1` `MB ``=` `1024` `kB (MB ``-` `megabajt) 237 | GB——吉比特 ``1` `GB ``=` `1024` `MB (GB ``-` `gigabajt) 238 | ``` 239 | 240 | 241 | 242 | #### 9.python递归的最大层数? 243 | 244 | ``` 245 | import sys 246 | sys.getrecursionlimit() # 获取最大递归层数 默认是1000(0-999) 247 | sys.setrecursionlimit(1200) # 设置最大递归层数 248 | ``` 249 | 250 | 251 | 252 | #### 10.解释 Python 中的 help() 函数和 dir() 函数。 253 | 254 | help() 函数返回帮助文档和参数说明: 255 | 256 | 运行结果如下: 257 | 258 | Help on function copy in module copy 259 | 260 | copy(x) 261 | 262 | Shallow copy operation on arbitrary Python objects. 263 | 264 | See the module』s __doc__ string for more info. 265 | 266 | dir() 函数返回对象中的所有成员 (任何类型) 267 | 268 | 269 | 270 | #### 11.当退出 Python 时是否释放所有内存分配? 271 | 272 | 答案是否定的。那些具有对象循环引用或者全局命名空间引用的变量,在 Python 退出是往往不会被释放 273 | 274 | 另外不会释放 C 库保留的部分内容。 275 | 276 | #### 12.什么是 Python 字典? 277 | 278 | 字典是我在 C++和 Java 中没有见过的数据结构,它拥有键-值对 279 | 280 | 3 281 | 282 | 字典是可变的,我们也可以用推导式的方式创建它. 283 | 284 | {25: 5, 16: 4, 9: 3, 4: 2, 1: 1} 285 | 286 | 要了解更多字典的内容请点击 Python Dictionaries( https://data-flair.training/blogs/python-dictionaries/) 287 | 288 | 289 | 290 | #### 13.*能否解释一下 \*args 和 \**kwargs? 291 | 292 | 如果我们不知道将多少个参数传递给函数,比如当我们想传递一个列表或一个元组值时,就可以使用*args。 293 | 294 | 3 295 | 296 | 2 297 | 298 | 1 299 | 300 | 4 301 | 302 | 7 303 | 304 | 当我们不知道将会传入多少关键字参数时,使用**kwargs 会收集关键字参数。 305 | 306 | a.1 307 | 308 | b.2 309 | 310 | c.7 311 | 312 | 使用 args 和 kwargs 作为参数名只是举例,可以任意替换。 313 | 314 | 对于 Python 的基础题任何疑问,请在评论区提问。 315 | 316 | 317 | 318 | #### 14.什么是负索引? 319 | 320 | 我们先创建如下列表: 321 | 322 | 与正索引不同,负索引是从右边开始检索。 323 | 324 | 6 325 | 326 | 同样可以用于列表的切片: 327 | 328 | [3, 4, 5, 6, 7] 329 | 330 | 331 | 332 | #### 15. 如何随机打乱列表中元素,要求不引用额外的内存空间? 333 | 334 | 我们用 random 包中的 shuffle() 函数来实现。 335 | 336 | [3, 4, 8, 0, 5, 7, 6, 2, 1] 337 | 338 | 339 | 340 | #### 16.解释 Python 中的 join() 和 split() 函数 341 | 342 | join() 函数可以将指定的字符添加到字符串中。 343 | 344 | ‘1,2,3,4,5’ 345 | 346 | split() 函数可以用指定的字符分割字符串 347 | 348 | [‘1’, ‘2’, ‘3’, ‘4’, ‘5’] 349 | 350 | 351 | 352 | #### 17.Python 区分大小写吗? 353 | 354 | 验证 Python 是否区分大小写的方法是测试 myname 和 Myname 在程序中是不是算同一个标识符。观察以下代码的返回结果: 355 | 356 | Myname 357 | 358 | NameError: name ‘Myname’ is not defined 359 | 360 | 如你所见,这里出现了 NameError,所以 Python 是区分大小的语言。 361 | 362 | 363 | 364 | #### 18.Python 中标识符的命名规则? 365 | 366 | Python 中的标识符可以是任意长度,但必须遵循以下命名规则: 367 | 368 | 1. 只能以下划线或者 A-Z/a-z 中的字母开头。 369 | 370 | 2. 其余部分只能使用 A-Z/a-z/0-9。 371 | 372 | 3. Python 标识符区分大小写。 373 | 374 | 4. 关键字不能作为标识符。Python 有以下这些关键字: 375 | 376 | ![img](https://t12.baidu.com/it/u=1852287917,3164344774&fm=173&app=25&f=JPEG?w=639&h=232&s=4CA03C7287744C225EFD41DA000080B1) 377 | 378 | #### 19.如何删除字符串中的前置空格 379 | 380 | 前置空格是第一个非空格字符前的所有空格,使用 lstrip() 函数来删除. 381 | 382 | ‘Ayushi ‘ 383 | 384 | 如图这个字符串既包含前置空格也包含后置空格. 调用 lstrip() 函数去除了前置空格。如果想去除后置空格,使用 rstrip() 函数。 385 | 386 | ‘ Ayushi’ 387 | 388 | 389 | 390 | #### 20.Python 中的 pass 语句有什么作用? 391 | 392 | 我们在写代码时,有时可能只写了函数声明而没想好函数怎么写,但为了保证语法检查的正确必须输入一些东西。在这种情况下,我们使用 pass 语句。 393 | 394 | 类似的 break 语句可以跳出循环。 395 | 396 | 0 397 | 398 | 1 399 | 400 | 2 401 | 402 | continue 语句可以跳到下一轮循环。 403 | 404 | 0 405 | 406 | 1 407 | 408 | 2 409 | 410 | 4 411 | 412 | 5 413 | 414 | 6 415 | 416 | #### 21.请解释 Python 中的闭包? 417 | 418 | 如果在一个内部函数里。对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就是一个闭包。 419 | 420 | 7 421 | 422 | 闭包的详细解释请点击 Closures in Python。(https://data-flair.training/blogs/python-closure/) 423 | 424 | 425 | 426 | #### 22.解释 Python 中的//,%和\**运算符 427 | 428 | //运算符执行地板除法,返回结果的整数部分 (向下取整)。 429 | 430 | 3 431 | 432 | 用/符号除法结果为 3.5。 433 | 434 | **符号表示取幂. a**b 返回 a 的 b 次方 435 | 436 | 1024 437 | 438 | % 是取模符号。返回除法后的余数。 439 | 440 | 6 441 | 442 | 0.5 443 | 444 | 445 | 446 | #### 23.Python 中有多少种运算符,解释算术运算符。 447 | 448 | 这类面试问题可以判断你的 Python 功底,可以举一些实例来回答这类问题。 449 | 450 | 在 Python 中我们有 7 中运算符:算术运算符、关系 (比较) 运算符、赋值运算符、逻辑运算符、位运算符、成员运算符、身份运算符。 451 | 452 | \1. 加号 (+) 将两个对象的值相加。 453 | 454 | 15 455 | 456 | \2. 减号 (-) 将第一个对象的值减去第二个对象的值。 457 | 458 | -1 459 | 460 | \3. 乘号 (*) 将两个对象的值相乘。 461 | 462 | 56 463 | 464 | \4. 除号 (/) 将第一个对象的值除以第二个对象的值。 465 | 466 | 0.875 467 | 468 | 1.0 469 | 470 | 关于地板除法、取模和取幂,请参考上一个问题。 471 | 472 | 473 | 474 | #### 24.解释 Python 中的关系运算符。 475 | 476 | 关系运算符用来比较两个对象。 477 | 478 | \1. 判断小于 (<):如果符号左边的值比右边小则返回 True。 479 | 480 | False 481 | 482 | \2. 判断大于 (>):如果符号左边的值比右边大则返回 True。 483 | 484 | True 485 | 486 | 出现上面的错误结果是因为 Python 的浮点运算存在一些 Bug。 487 | 488 | \3. 判断小于等于 (<=):如果符号左边的值小于或等于右边则返回 True。 489 | 490 | True 491 | 492 | \4. 大判断于等于 (>=):如果符号左边的值大于或等于右边则返回 True。 493 | 494 | True 495 | 496 | \5. 判断等于 (==) 如果符号两边的值相等则返回 True。 497 | 498 | True 499 | 500 | \6. 判断不等于 (!=) 如果符号两边的值不等则返回 True。 501 | 502 | True 503 | 504 | True 505 | 506 | 507 | 508 | #### 25.解释 Python 中的位运算符 509 | 510 | 此运算符按二进制位对值进行操作。 511 | 512 | \1. 与 (&) 返回按位与结果 513 | 514 | 2 515 | 516 | \2. 或 (|) 返回按位或结果 517 | 518 | 3 519 | 520 | \3. 异或 (^) 返回按位异或结果 521 | 522 | 1 523 | 524 | \4. 取反 (~) 返回按位取反结果 525 | 526 | -3 527 | 528 | \5. 左移位 (<<) 将符号左边数的二进制左移右边数位 529 | 530 | 4 531 | 532 | 1 的二级制 001 左移 2 位变成 100 也即十进制的 4 533 | 534 | \6. 右移位 (>>) 535 | 536 | 1 537 | 538 | 想了解关于位运算符的更多内容请点击 Operators in Python(https://data-flair.training/blogs/python-operators/) 539 | 540 | 541 | 542 | #### 26.如何在 Python 使用多进制数字? 543 | 544 | 除十进制以外,在 Python 中还可以使用二进制、八进制、十六进制。 545 | 546 | \1. 二进制数有 0 和 1 组成,我们使用 0b 或 0B 前缀表示二进制数 547 | 548 | 10 549 | 550 | 使用 bin() 函数可以将数字转换为二进制 551 | 552 | ‘0b1111’ 553 | 554 | \2. 八进制数由数字 0-7 组成,使用前缀 0o 或 0O 表示 8 进制数 555 | 556 | ‘0o10’ 557 | 558 | \3. 十六进数由数字 0-15 组成,使用前缀 0x 或者 0X 表示 16 进制数 559 | 560 | ‘0x10’ 561 | 562 | ‘0xf’ 563 | 564 | #### 27.如何获取字典中的所有键? 565 | 566 | 使用 keys() 来获取字典中的所有键 567 | 568 | #### 28.问什么标识符不建议使用下划线开头? 569 | 570 | 因为在 Python 中以下划线开头的变量为私有变量,如果你不想让变量私有,就不要使用下划线开头。 571 | 572 | #### 29.什么是元组的解封装? 573 | 574 | 首先我们来介绍元组封装: 575 | 576 | 577 | 578 | (3, 4, 5) 579 | 580 | 将 3,4,5 封装到元组 mytuple 中。 581 | 582 | 现在我们要将这些值解封装到变量 x,y,z 中 583 | 584 | 12 585 | 586 | #### 30.Python3和Python2中 int 和 long的区别? 587 | 588 | python2有非浮点数准备的``int``和``long``类型。``int``类型最大值不能超过sys.maxint,而且这个最大值是平台相关的。 589 | 590 | 可以通过在数字的末尾附上一个L来定义长整型,显然,它比``int``类型表示的数字范围更大。 591 | 592 | python3里,只有一种整数类型``int``,大多数情况下,和python2中的长整型类似。 593 | 594 | #### 31.列举 Python 中的基本数据类型? 595 | 596 | Python3中有6种基本数据类型,列表(list)、元组(tuble)、字典(dict)、集合(sets)、字符串(string)、数字(digit)。 597 | 598 | 599 | 600 | #### 32.将"hello world"转换为首字母大写"Hello World 601 | 602 | ``` 603 | “hello world”.title() 604 | ``` 605 | 606 | 607 | 608 | #### 33.如何检测字符串中只含有数字? 609 | 610 | ``` 611 | '123bp'.isdigit()----------返回True or False 612 | #或者使用正则: 613 | bool(re.search(r’\d’,’qw123’)) 614 | #或者使用Unicode码: 615 | if uchar >= u'\u0030' and uchar <= u'\u0039' 616 | ``` 617 | 618 | 619 | 620 | #### 34.将字符串"ilovechina"进行反转 621 | 622 | ``` 623 | "ilovechina"[::-1] 624 | ``` 625 | 626 | 627 | 628 | #### 35.Python 交换两个变量的值 629 | 630 | a, b = b, a 631 | 632 | #### 36.Python 里面如何实现 tuple 和 list 的转换? 633 | 634 | ``` 635 | tuple(list) 636 | ``` 637 | 638 | #### 37.Python 中的字符串格式化方式你知道哪些? 639 | 640 | ``` 641 | 'I %s her %s'%('love','cat') 642 | 'I {a} her {b}'.format(a='love',b='cat') 643 | f'I {a} her {b}' #【Python3.6推荐写法】 644 | ``` 645 | 646 | #### 38.如何对list去重? 647 | 648 | 1)先建立一个新的空列表,通过遍历原来的列表,再利用逻辑关系not in 来去重。此方法保证了列表的顺序性。 649 | 650 | ``` 651 | li=[1,2,3,4,5,1,2,3] 652 | new_li=[] 653 | for i in li: 654 | if i not in new_li: 655 | new_li.append(i) 656 | print(new_li) 657 | 658 | ``` 659 | 660 | 2)将列表转化为集合再转化为列表,利用集合的自动去重功能。简单快速。缺点是:使用set方法无法保证去重后的顺序。 661 | 662 | ``` 663 | li=[1,2,3,4,5,1,2,3] 664 | new_li=list(set(li)) 665 | new_li.sort(key=li.index) 666 | print(new_li) 667 | 668 | ``` 669 | 670 | #### 39.给定两个 list,A 和 B,找出相同元素和不同元素 671 | 672 | ``` 673 | A、B 中相同元素:set(A)&set(B) 674 | A、B 中不同元素:set(A)^set(B) 675 | ``` 676 | 677 | #### 40.如何打乱一个列表的元素? 678 | 679 | ``` 680 | random.shuffle(l1) 681 | ``` 682 | 683 | #### 41.字典操作中 del 和 pop 有什么区别 684 | 685 | del d[key] 直接删除 686 | d.pop(key) 返回键的值 687 | 688 | #### 42.请合并下面两个字典 a = {“A”:1,“B”:2},b = {“C”:3,“D”:4} 689 | 690 | ``` 691 | a.update(b) 692 | ``` 693 | 694 | #### 43.如何把元组 (“a”,“b”) 和元组 (1,2),变为字典 {“a”:1,“b”:2} 695 | 696 | ``` 697 | dict(zip(a,b)) 698 | ``` 699 | 700 | #### 44.如何交换字典 {“A”:1,“B”:2}的键和值 701 | 702 | ``` 703 | {value:key for key value in dict.items()} 704 | 705 | ``` 706 | 707 | #### 45.切片Slice 708 | 709 | 切片,是一个比较生疏的名词,这是现代计算机编程语言或者说Python里的一个概念,大致意思是从一个集合里切出一块来,就像切一块豆腐,一刀下去切出两块豆腐,问题是两刀能切出几块?开个小玩笑! 710 | 711 | 先看一个函数range、返回值是列表,内容和传入range的函数有关。 712 | 713 | ``` 714 | a = range(1, 21) 715 | print a 716 | ``` 717 | 718 | 结果 719 | 720 | ``` 721 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 722 | ``` 723 | 724 | 明白了,range可以产生从1到20共20个元素的列表,range的第二个参数不包含这个值,但包含第一个参数的值,每个元素值相差为1。 725 | 726 | #### 46.什么是切片 727 | 728 | 回到正题,切片是对有序的集合而言,意思从有序集合里提取数据构成子集集合,给定提取的起点start、终点end以及方向上的步长step,**能否切出非空子集,起点start需能沿步长方向上到达终点**。 729 | 730 | 字符串和列表、元组都是有序集合,均可实现切片操作,以列表为例给出切片的语法格式如下: 731 | 732 | ``` 733 | 子集名 = 有序集合名[start : end : step] 734 | ``` 735 | 736 | 上边range(1, 21)和切片里的start、end是呼应一致的,含起点start对应的值而不含终点end所对应的值。 737 | 738 | #### step = 1 739 | 740 | 子集的构成是从start开始每step取一个数据一至到end-1位置结束,step默认为1时,可以省略不写。 741 | 742 | ``` 743 | s = "python" 744 | a = list(s) 745 | print a 746 | b = a[2:5] 747 | print b 748 | ``` 749 | 750 | 程序的结果如下: 751 | 752 | ``` 753 | ['p', 'y', 't', 'h', 'o', 'n'] 754 | ['t', 'h', 'o'] 755 | ``` 756 | 757 | | 0 | 1 | 2 | 3 | 4 | 5 | 758 | | ---- | ---- | ---- | ---- | ---- | ---- | 759 | | 'p' | 'y' | 't' | 'h' | 'o' | 'n' | 760 | 761 | 从print b这条语句的打印结果['t', 'h', 'o']可知,'t'在a列表的index为2,'n'字符的index为5,那么a[2:5]的step为1,从't'开始逐个取回字符't'、'h'、'o'组成新的列表的子集b,而字符'n'的index为5,5作为取切片操作a[2:5]里的终点,其字符'n'不取回。从例子可以看出step 为1可以理解为“逐个取”。 762 | 763 | #### step > 1 764 | 765 | step可以大于1,这个时候对于step的理解可以这样认为,每step个取一个。 766 | 767 | ``` 768 | s = "python" 769 | a = list(s) 770 | print a 771 | b = a[2:5:2] 772 | print b 773 | ``` 774 | 775 | 程序的结果如下: 776 | 777 | ``` 778 | ['p', 'y', 't', 'h', 'o', 'n'] 779 | ['t', 'o'] 780 | ``` 781 | 782 | 对于列表a取切片a[2 : 5 : 2], 从index为2开始,每2个元素为一组取每组的第一个数据值,一只到index为5结束,但不取index为5的数据。 783 | 784 | a[2 : 5 : 2]具体操作是这样的,从index为2的字符't'开始,到index为5的字符'n'之前,每2个为一组('t', 'h')、('o', 'n')取每组的第一个元素值't'、'o'即结果子集b的值。 785 | 786 | 再看一个例子: 787 | 788 | ``` 789 | a = range(12) 790 | print a 791 | b = a[1 : 10 : 3] 792 | print b 793 | ``` 794 | 795 | 结果是: 796 | 797 | ``` 798 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 799 | [1, 4, 7] 800 | ``` 801 | 802 | 从两行输出结果的第一行可以看出range函数可以产生一个从0开始到小于12的整数的列表,共12个数据。 803 | 804 | 第二行的输出[1, 4, 7]是怎么产生的呢?这个和对a列表的切片操作有关,a[1 : 10 : 3],这里a[1:10] = [1, 2, 3, 4, 5, 6, 7, 8, 9],每3个一组,从每组取第一个,即 [1, 2, 3],[4, 5, 6], [7, 8, 9]这三组,取每组第一个1、4、7构成b这个子集,最后得到的b = [1, 4, 7]。 805 | 806 | #### 47.元组的定义 807 | 808 | 定义一个元组很简单,将一堆数据用圆括号括起来,用逗号间隔各个元素即可定义一个元组,元组里的数据是只读的不可被修改。 809 | 810 | ``` 811 | 变量名 = (元素值序列) 812 | ``` 813 | 814 | #### 48.字符串的三种引号 815 | 816 | ``` 817 | print 'hello' 818 | print "hello" 819 | print '''hello''' 820 | print """hello""" 821 | ``` 822 | 823 | 一般三引号可以在Python源代码里用作多行注释或定义多行的字符串,另外Python可以用井号(#)进行单行注释。 824 | 825 | ``` 826 | a = 12 827 | b = 13 828 | """ 829 | 求和 830 | """ 831 | c = a + b 832 | ``` 833 | 834 | 字符串是有序不可修改的序列,可以通过索引或者for循环体访问字符串里的各个元素值。 835 | 836 | ``` 837 | s = "python" 838 | print s[1] 839 | for c in s: 840 | printc 841 | ``` 842 | 843 | #### 49.字典dict访问 844 | 845 | 通过键值 846 | 847 | 字典的数据是由key:value对儿构成的每项数据,那么想访问某项数据的value需要可以通过[]运算来获得,其语法结构如下: 848 | 849 | ``` 850 | 字典名[key] 851 | ``` 852 | 853 | 字典的get函数 854 | 855 | 字典有个等价函数get可以获得这种方式的相同结果,语法结构如下: 856 | 857 | ``` 858 | 字典名.get(key) 859 | ``` 860 | 861 | get函数返回值就是这个key所对应的值。 862 | 863 | 例如: 864 | 865 | ``` 866 | d = {1 : 2, "a" : 13, 12.4 : 77} 867 | print d.get("a") 868 | ``` 869 | 870 | 但是如果无key的话,get返回None而不会报错发生异常,而用[]运算即`字典名[key]`则会报错异常。 871 | 872 | #### 50.字典的setdefault函数 873 | 874 | 还有一个函数setdefault() 函数,它和get函数类似,返回指定键的值,如果键不在字典中,将会添加键并将值设置为一个指定值,默认为None。 875 | 876 | get() 和 setdefault() 区别: setdefault() 返回的键如果不在字典中,会添加键(更新字典),而 get() 不会添加键。 877 | 878 | #### 参考链接 879 | 880 | https://www.jianshu.com/p/373cdf20039d 881 | 882 | https://blog.csdn.net/qdPython/article/details/101286827 883 | 884 | https://blog.csdn.net/pangzhaowen/article/details/80650478 885 | 886 | https://blog.csdn.net/Xidian2850/article/details/108171194 887 | 888 | http://liao.cpython.org/ 889 | 890 | https://baijiahao.baidu.com/s?id=1607651363840614527&wfr=spider&for=pc 891 | 892 | https://www.cnblogs.com/tianyiliang/p/7845932.html 893 | 894 | https://blog.csdn.net/qq_40082282/article/details/102914050 895 | 896 | 897 | 898 | 899 | --------------------------------------------------------------------------------