├── .gitignore ├── 01-Python语法 ├── 00-Python简介.md ├── 01-语法初识.md ├── 02-数据类型.md ├── 03-流程控制.md ├── 04-引用类型.md ├── 05-函数.md ├── 07-面向对象-类与对象.md ├── 08-面向对象-三大特性.md ├── 09-面向对象-补充.md ├── 10-异常.md ├── 11-模块.md └── 12-Python2与Python3.md ├── 02-并发与网络 ├── 01-多进程.md ├── 02-多线程.md ├── 03-协程.md └── 04-Socket编程.md ├── 03-Web编程 ├── 01-Web服务器实现.md ├── 02-Python连接数据库示例.md └── 03-Flask.md ├── LICENSE ├── README.md ├── images └── python │ ├── 01-00.jpeg │ ├── 01-01.png │ ├── 01-02.png │ ├── aa-01.png │ └── aa-02.png ├── 数据分析篇 ├── 01-数据分析概述.md ├── 02-科学计算工具NumPy-1-数据类型.md ├── 02-科学计算工具NumPy-2-矩阵处理.md └── 04-可视化工具-matplotlib.md └── 机器学习篇 └── 01-机器学习初识.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /01-Python语法/00-Python简介.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | > 人生苦短,我用 Python —— Life is short, you need Python 4 | 5 | ## 一 Python简介 6 | 7 | Python的开发始于1989年,作者是 Guido von Rossum,1.0版正式发布于1994年,并于2000年发布了重要版本2.0,在该版本中实现了完整的垃圾回收,提供了对Unicode的支持,生态开始繁荣。 8 | 9 | 2000年,Python3发布,该版本不完全兼容之前的Python代码,不过因为目前还有不少公司在项目和运维中使用Python 2.x版本,所以Python 3.x的很多新特性后来也被移植到Python 2.6/2.7版本中。 10 | 11 | Python的Logo: 12 | ![](../images/python/01-00.jpeg) 13 | 14 | ## 二 Python的特点 15 | 16 | 笔者认为Python最强大的优点有以下三处: 17 | - 简洁:做一件事只有一种方法,学习曲线低,容易上手。 18 | - 生态:代码开源,拥有强大的社区和生态圈,标准库极其强大。 19 | - 扩展:是很好的胶水语言,可以调用C/C++代码,也可以在C/C++中调用Python。 20 | 21 | Python的缺点主要集中在以下几点: 22 | - 执行效率稍低:计算密集型任务需要借助C/C++ 23 | - 过简语法造成大项目的工程化重构难题 24 | 25 | Python目前主要应用于:科学计算、运维、爬虫。Python在Web市场中占比极小,不能与Java、Php相比,现在甚至还不及Node.js的繁荣。 26 | 27 | ## 三 Python安装 28 | 29 | ### 3.0 py2与py3 30 | 31 | Python拥有2个互不兼容的版本:Python2和Python3,当前推荐使用Python3。当然,某些工具库还没有提供支持 Python 3.x。 32 | 33 | Python拥有下列两种常见的安装方式 34 | - 官网下载安装:[网址](https://www.python.org/),该方式适合python语法学习,web开发,爬虫开发,运维开发等场景 35 | - 科学环境安装:[安装科学集成环境Anaconda](https://www.continuum.io/downloads),该环境内置了python以及其他科学运算包,适合人工智能领域使用 36 | 37 | ### 3.1 Win安装Python 38 | 39 | 前往[官网](https://www.python.org/)下载对应操作系统的python安装包后,下一步下一步即可。 40 | 41 | 注意: 42 | - 安装目录建立使用无空格的英文目录 43 | - win7系统需要预先安装Service Pack 1补丁包、Visual C++ Redistributable for Visual Studio 2015等动态库 44 | - win7安装时,建议勾选`Add Python 3 to PATH`,并在`Optional Features`界面勾选`“pip”、“tcl/tk”、“Python test suite”` 45 | 46 | ### 3.2 Mac安装Python 47 | 48 | Mac自带了Python2版本,打开命令行工具输入: 49 | ``` 50 | python # 此时即可进入python2环境 51 | ``` 52 | 53 | Mac也可以额外安装Python3,让Python2和Python3共存。下载[官网](https://www.python.org/)的3.x版本pkg安装包即可,输入如下命令: 54 | ``` 55 | python3 # 此时可进入python3环境 56 | exit() # 退出环境 57 | ``` 58 | 59 | ### 3.3 CentOS环境 60 | 61 | Linux环境自带Python 2.x版本,输入如下命令查看: 62 | ``` 63 | python # 此时即可进入python2环境 64 | ``` 65 | 66 | CentOS安装Python3需要使用源码编译方式安装,先安装依赖环境: 67 | ``` 68 | yum -y install wget gcc zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel 69 | ``` 70 | 71 | Python3安装: 72 | ``` 73 | # 下载Python3 74 | wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz 75 | xz -d Python-3.7.4.tar.xz 76 | tar -xvf Python-3.7.4.tar 77 | 78 | # 安装Python3 79 | cd Python-3.7.4 80 | ./configure --prefix=/usr/local/python3 --enable-optimizations 81 | make && make install 82 | 83 | # 配置环境变量 84 | vim ~/.bash_profile 85 | export PATH=$PATH:/usr/local/python3/bin 86 | source ~/.bash_profile 87 | 88 | # 测试python3环境 89 | python3 90 | 91 | # 退出环境 92 | exit() 93 | ``` 94 | 95 | ## 四 科学环境安装 96 | 97 | 科学环境主要自动集成了一些科学运算包,方便数据分析、机器学习。如果是语法学习、web开发、爬虫开发则无需该环境。 98 | 99 | 当前Python的科学环境的集成安装包是 [Anaconda](https://www.continuum.io/downloads),该环境包含了 conda命令、Python等 180 多个科学计算包及其依赖项,并且支持所有操作系统平台。 100 | 101 | Anaconda 安装后创建环境: 102 | ``` 103 | # 创建环境 104 | conda create --name python3 python=3 105 | 106 | # win切换环境 107 | conda activate python3 108 | 109 | # mac/linux切换环境 110 | source activate python3 111 | 112 | # 输入如下命令即可查看当前python环境是否已经切换到conda环境: 113 | which python 114 | ``` 115 | 116 | 安装Anaconda后,将会自带下列软件: 117 | - Python:依据选择的Anaconda,决定python的版本 118 | - Jupyter:一款编程/文档/展示软件,启动命令:`jupyter notebook`,可以实时查看运行过程,记录历史运行结果 119 | - Sypder:适合熟悉Matlab的用户,使用简单的图形界面开发环境 120 | - IPython:交互式命令行 Shell,唤起命令`ipython` 121 | 122 | conda和pip类似,均为安装、卸载或管理Python第三方包: 123 | - conda install 包名 pip install 包名 124 | - conda uninstall 包名 pip uninstall 包名 125 | - conda install -U 包名 pip install -U 包名 126 | 127 | conda管理数据科学环境步骤: 128 | ``` 129 | # 打开Anaconda Prompt窗口,执行: 130 | conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ 131 | conda config --set show_channel_urls yes 132 | 133 | # 在用户目录下找到.condarc文件,删除第3行 -defaults 134 | ``` -------------------------------------------------------------------------------- /01-Python语法/01-语法初识.md: -------------------------------------------------------------------------------- 1 | ## 一 HelloWorld 2 | 3 | 新建文件`hello.py`,内容如下: 4 | ```py 5 | print('hello, world!') 6 | ``` 7 | 8 | 运行`hello.py`: 9 | ``` 10 | python3 hello.py # 注意:如果使用命令为 python,则启用python2解释器 11 | hello, world! 12 | ``` 13 | 14 | 推荐的Python开发工具室VSCode、Pycharm。这里要注意的是:Pycharm打开hello.py所在的文件夹后,是不识别pythonSDK(包含解释器)的,点击File-Project Structure-设置SDK,也可以新建自定义SDK目录,以mac为示例: 15 | 16 | ![](../images/python/01-01.png) 17 | 18 | SDK设置完毕后,需要设置当前项目启用该SDK: 19 | 20 | ![](../images/python/01-02.png) 21 | 22 | ## 二 Python的解释器 23 | 24 | Python的解析器(Interpreter),即解析执行Python源码的程序,HelloWorld程序能够运行依靠的就是安装Python时候默认的内置解释器:CPython。 25 | 26 | Python解析器有多种: 27 | - CPython:官方提供默认解析器,由于使用C语言实现,所以称之为CPython。 28 | - JPython:使用Java语言实现的Python解析器,将Python代码编程成Java字节码执行。 29 | - IronPython:是运行在微软Net平台上的Python解析器,直接把Python代码编译成Net字节码。 30 | - PyPy:使用Python语言实现的Python解析器。 31 | 32 | 输入如下命令,可以查看当前使用的python解释器 33 | ``` 34 | which python 35 | ``` 36 | 37 | ## 三 注释 38 | 39 | 单行注释: 40 | ```py 41 | # 这是第一个单行注释 42 | print("hello python") 43 | ``` 44 | 45 | 多行注释: 46 | ```py 47 | ''' 48 | 这是一个多行注释 49 | 这是一个多行注释 50 | ''' 51 | print("hello python") 52 | ``` 53 | 54 | ## 四 中文支持 55 | 56 | python3默认支持中文,但是在python2中需要在源码第一行额外添加: 57 | ```py 58 | #coding=utf-8 59 | print('你好') 60 | ``` 61 | 62 | 注意,在python的语法规范中推荐使用的方式: 63 | ```py 64 | # -*- coding:utf-8 -*- 65 | ``` 66 | 67 | ## 五 输入输出 68 | 69 | ### 5.1 格式化输出 70 | 71 | 输出用于在命令行中显示数据: 72 | ```py 73 | print("我今年12岁") 74 | ``` 75 | 76 | 格式化输出: 77 | ```py 78 | age = 10 79 | print("我今年%d岁" % age) 80 | ``` 81 | 82 | 换行输出: 83 | ```py 84 | print("12345\n67890") 85 | ``` 86 | 87 | 常见格式化符号: 88 | ``` 89 | %c 字符 90 | %s 字符串 91 | %d 有符号十进制整数 92 | %u 无符号十进制整数 93 | %o 八进制整数 94 | %x 十六进制整数(小写字母0x) 95 | %X 十六进制整数(大写字母0X) 96 | %f 浮点数 97 | %e 科学计数法(小写'e') 98 | %E 科学计数法(大写“E”) 99 | %g %f和%e 的简写 100 | %G %f和%E的简写 101 | ``` 102 | 103 | ### 5.2 输入 104 | 105 | 输入用于获取键盘输入的数据,常见的输入函数是 `input()`, 106 | ```py 107 | password = input("请输入密码:") 108 | print('您刚刚输入的密码是:%s' % password) 109 | ``` 110 | 111 | input函数还能接收表达式: 112 | ```py 113 | >>> a = input() 114 | 1+3 115 | >>> a 116 | 4 117 | ``` 118 | 119 | 在python2中,还支持 `raw_input()`函数来接收普通的输入。 120 | 121 | ## 六 运算符 122 | 123 | - 算术运算符:`+ - * /(除)%(取模,即取余) **(幂) //(去整除)` 124 | - 比较运算符:` == != > < >= <= ` 125 | - 赋值运算符:` = += -= *= /= %= **= //= ` 126 | - 位运算符:` & | ^ ~ << >> ` 127 | - 逻辑运算符:`and or not` 128 | - 成员运算符:`in not int` 129 | - 身份运算符:` is is not ` 130 | 131 | ## 七 优先级 132 | 133 | ``` 134 | ** 指数 (最高优先级) 135 | ~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) 136 | * / % // 乘,除,取模和取整除 137 | + - 加法减法 138 | >> << 右移,左移运算符 139 | & 位 'AND' 140 | ^ | 位运算符 141 | <= < > >= 比较运算符 142 | <> == != 等于运算符 143 | = %= /= //= -= += *= **= 赋值运算符 144 | is is not 身份运算符 145 | in not in 成员运算符 146 | not and or 逻辑运算符 147 | ``` -------------------------------------------------------------------------------- /01-Python语法/02-数据类型.md: -------------------------------------------------------------------------------- 1 | ## 一 数据类型 2 | 3 | ### 1.1 标识符 4 | 5 | 标识符是源码中具备一定语意的命名,开发者在命名时候也需要遵循一定的规范: 6 | ``` 7 | 不能以数字开头 8 | 不能包含特殊字符 9 | 不能是关键字 10 | Python中一些下划线开头的标识符具有特殊意义 11 | ``` 12 | 13 | 多个单词可以采用驼峰命名方式,或者下划线方式: 14 | ```py 15 | # 驼峰 16 | userName = "Green" 17 | 18 | # 下划线 19 | orderTime = "2012/12/12" 20 | ``` 21 | 22 | ### 1.2 关键字 23 | 24 | 被Python官方使用的标识符,即关键字有: 25 | ``` 26 | and as assert break class continue def del 27 | elif else except exec finally for from global 28 | if in import is lambda not or pass 29 | print raise return try while with yield 30 | ``` 31 | 在python执行换将中,可以使用命令查看有哪些关键字: 32 | ```py 33 | import keyword 34 | keyword.kwlist 35 | ``` 36 | 37 | ### 1.3 变量 38 | 39 | 变量即存储数据的空间,使用标识符来为变量命名。为了更充分的利用内存空间以及更有效率的管理内存,变量是有不同的类型的。 40 | 41 | Python的数据类型有六个: 42 | - Numbers:数字类型,包括 `int(有符号整数)`、`long(长整型)`、`float(浮点型)`、`complex(复数)` 43 | - Boolean:布尔类型,包括`True`、`False` 44 | - String:字符串类型 45 | - List:列表 46 | - Tuple:元组 47 | - Dictinoary:字典 48 | 49 | Python是弱类型语言,开发者无需主动说明数据的类型,在声明时候系统会自动识别。 50 | 51 | Python也允许多变量赋值: 52 | ```py 53 | a = b = c = 1 54 | print(a) 55 | print(b) 56 | print(c) 57 | ``` 58 | 59 | ## 二 数字类型 60 | 61 | Python3 支持 int、float、bool、complex(复数)。在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。内置的 type() 函数可以用来查询变量所指的对象类型。 62 | 63 | ```py 64 | a, b, c, d = 20, 5.5, True, 4+3j 65 | print(type(a), type(b), type(c), type(d)) 66 | ``` 67 | 68 | 输出类型结果如下: 69 | ``` 70 | 71 | ``` 72 | 73 | ## 三 字符串类型 74 | 75 | ### 3.1 字符串定义与下标 76 | 77 | Python中的字符串用单引号 ' 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符。 78 | 79 | ```py 80 | str = 'hello' 81 | 82 | print(str) 83 | print(str[0]) 84 | print(str[0:-1]) 85 | print(str[0:2]) 86 | print(str[2:]) 87 | print(str * 2) 88 | print(str + " ruyue") 89 | ``` 90 | 91 | 输出结果如下: 92 | ``` 93 | hello 94 | h 95 | hell 96 | he 97 | llo 98 | hellohello 99 | hello ruyue 100 | ``` 101 | 102 | Python 使用反斜杠(\)转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串: 103 | ```py 104 | print(r'ru\nyue') # 输出ru\nyue 105 | ``` 106 | 107 | 注意:、Python 字符串不能被改变。向一个索引位置赋值,比如word[0] = 'm'会导致错误。 108 | 109 | ### 3.2 字符串常见方法 110 | 111 | 查找方法`find()`和`index()`:查看参数是否在字符串中,是则返回所在索引,否则返回-1 112 | ```py 113 | str = 'hello' 114 | print(str.find('h')) # 0 115 | print(str.find('h', 1, 5)) # -1 后续2个可选参数为歧视位置、结束位置 116 | 117 | # index() 方法用法与find()一致,但是在没有找到数据时报错 118 | ``` 119 | 120 | 次数方法`count()`:获取参数在字符串中存在的个数 121 | ```py 122 | str = 'hello' 123 | print(str.count('h')) # 1 124 | print(str.count('h', 1, 5)) # 0 125 | ``` 126 | 127 | 替换方法`replace()`: 128 | ```py 129 | str1 = 'hello' 130 | print(str1.replace('l', 'k')) # hekko 131 | 132 | str2 = 'hello' 133 | print(str2.replace('l', 'k', 1)) # heklo 第三个参数代表替换次数 134 | ``` 135 | 136 | 分割方法`split()`: 137 | ```py 138 | str = 'he ll o' 139 | print(str.split(' ')) # ['he', 'll', 'o'] 140 | ``` 141 | 142 | 其他常见方法: 143 | ``` 144 | rfind() 类似find,从右侧查找 145 | rindex() 类似index,从右侧查找 146 | partition() 将字符串分割为三部分:参数前,参数,参数后 147 | capitalize() 首字符大写 148 | title() 每个单词首字母大写 149 | startswith() 检查字符串是否以参数开头,返回布尔 150 | endswith() 检查字符串是否以参数结尾,返回布尔 151 | lower() 所有大写转小写 152 | upper() 所有小写转大写 153 | lstrip() 清除左边空白 154 | rstrip() 清除右边空白 155 | ``` 156 | 157 | ## 四 元组类型 158 | 159 | 该类型与列表类似,在下一节介绍。 160 | 161 | ## 五 数据类型转换 162 | 163 | 常见转换函数: 164 | ``` 165 | int(x [,base ]) 将x转换为一个整数 166 | float(x) 将x转换为一个浮点数 167 | complex(real [,imag ]) 创建一个复数,real为实部,imag为虚部 168 | str(x) 将对象 x 转换为字符串 169 | repr(x) 将对象 x 转换为表达式字符串 170 | eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象 171 | tuple(s) 将序列 s 转换为一个元组 172 | list(s) 将序列 s 转换为一个列表 173 | chr(x) 将一个整数转换为一个Unicode字符 174 | ord(x) 将一个字符转换为它的ASCII整数值 175 | hex(x) 将一个整数转换为一个十六进制字符串 176 | oct(x) 将一个整数转换为一个八进制字符串 177 | bin(x) 将一个整数转换为一个二进制字符串 178 | ``` -------------------------------------------------------------------------------- /01-Python语法/03-流程控制.md: -------------------------------------------------------------------------------- 1 | ## 一 条件控制 2 | 3 | ### 1.1 if条件句 4 | 5 | ```py 6 | var1 = 100 7 | if var1: 8 | print ("1 - if 表达式条件为 true") 9 | print (var1) 10 | 11 | var2 = 0 12 | if var2: 13 | print ("2 - if 表达式条件为 true") 14 | print (var2) 15 | print ("Good bye!") 16 | ``` 17 | 18 | ### 1.2 if嵌套 19 | 20 | if-else: 21 | ```py 22 | num=int(input("输入一个数字:")) 23 | if num%2==0: 24 | if num%3==0: 25 | print ("你输入的数字可以整除 2 和 3") 26 | else: 27 | print ("你输入的数字可以整除 2,但不能整除 3") 28 | else: 29 | if num%3==0: 30 | print ("你输入的数字可以整除 3,但不能整除 2") 31 | else: 32 | print ("你输入的数字不能整除 2 和 3") 33 | ``` 34 | 35 | ### 1.3 elseif 36 | ```py 37 | score = 77 38 | if score>=90 and score<=100: 39 | print('本次考试,等级为A') 40 | elif score>=80 and score<90: 41 | print('本次考试,等级为B') 42 | elif score>=70 and score<80: 43 | print('本次考试,等级为C') 44 | elif score>=60 and score<70: 45 | print('本次考试,等级为D') 46 | elif score>=0 and score<60: 47 | print('本次考试,等级为E') 48 | ``` 49 | 50 | 贴士:elif必须和if一起使用,否则出错,else 一般用在最后,即所有条件都不满足时使用,可以和 elif 配合使用。 51 | 52 | ## 二 循环语句 53 | 54 | ### 2.1 for循环 55 | ```py 56 | languages = ["C", "C++", "Perl", "Python"] 57 | for x in languages: 58 | print (x) 59 | ``` 60 | ### 2.2 for range 61 | 62 | ```py 63 | for i in range(5): 64 | print(i) 65 | ``` 66 | 67 | ### 2.3 while循环 68 | 69 | ```py 70 | n = 100 71 | 72 | sum = 0 73 | counter = 1 74 | while counter <= n: 75 | sum = sum + counter 76 | counter += 1 77 | 78 | print("1 到 %d 之和为: %d" % (n,sum)) 79 | ``` 80 | 81 | 简单使用: 82 | ```py 83 | flag = 1 84 | while (flag): print ('欢迎访问菜鸟教程!') 85 | print ("Good bye!") 86 | ``` 87 | 88 | ## 三 跳出循环 89 | 90 | ### 3.1 break 91 | ```py 92 | for letter in 'Runoob': # 第一个实例 93 | if letter == 'b': 94 | break 95 | print ('当前字母为 :', letter) 96 | 97 | var = 10 # 第二个实例 98 | while var > 0: 99 | print ('当期变量值为 :', var) 100 | var = var -1 101 | if var == 5: 102 | break 103 | 104 | print ("Good bye!") 105 | ``` 106 | 107 | ### 3.2 continue 108 | 109 | ```py 110 | for letter in 'Runoob': # 第一个实例 111 | if letter == 'o': # 字母为 o 时跳过输出 112 | continue 113 | print ('当前字母 :', letter) 114 | 115 | var = 10 # 第二个实例 116 | while var > 0: 117 | var = var -1 118 | if var == 5: # 变量为 5 时跳过输出 119 | continue 120 | print ('当前变量值 :', var) 121 | print ("Good bye!") 122 | ``` 123 | 124 | ### 3.3 pass 125 | 126 | ```py 127 | for letter in 'Runoob': 128 | if letter == 'o': 129 | pass 130 | print ('执行 pass 块') 131 | print ('当前字母 :', letter) 132 | 133 | print ("Good bye!") 134 | ``` -------------------------------------------------------------------------------- /01-Python语法/04-引用类型.md: -------------------------------------------------------------------------------- 1 | ## 一 值类型与引用类型 2 | 3 | 在Python中,数据类型大致有两类: 4 | - 值类型:本身不允许被修改,有:数值类型、布尔类型、字符串类型、元组类型等 5 | - 引用类型:本身允许修改,有:列表、字典 6 | 7 | python的变量无类型限制,其实是因为变量的本质是指针,可以指向任意对象。指针的内存空间大小是与类型无关的,其内存空间只是保存了所指向数据的内存地址。 8 | 9 | 以下示例其实是让a指向一个新的内存地址,并不会修改变量b的值: 10 | ```py 11 | a = 1 12 | b = a 13 | a = 2 14 | print(b) #输出的结果是1 15 | ``` 16 | 17 | 而在引用类型中,就不会有上述情况的产生。 18 | 19 | ## 二 引用类型-列表 20 | 21 | 列表可以简单理解为其他编程语言的数组,列表内的数据支持不同的类型: 22 | ```py 23 | namesList = ['xiaoWang','xiaoZhang','xiaoHua'] 24 | print(namesList[0]) 25 | print(len(namesList)) 26 | for name in namesList: 27 | print(name) 28 | ``` 29 | 30 | 列表也支持嵌套: 31 | ```py 32 | cityList = [ 33 | ['北京', '上海'] 34 | ['郑州', '长沙', '西安'] 35 | ] 36 | ``` 37 | 38 | 列表常见操作: 39 | ```py 40 | list = ['a', 'b', 'c'] 41 | 42 | # 添加元素 43 | list.append('d') # 尾部添加 44 | list.extend(['e', 'f']) # 逐个添加 45 | list.insert(6, 'g') # 指定位置添加 46 | 47 | # 删除元素 48 | del list[0] # 删除指定位置 49 | list.pop() # 删除末尾元素 50 | list.remove('g') # 删除具体元素 51 | 52 | # 修改元素 53 | list[0] = 'A' 54 | 55 | # 查找元素,index/count 等方法与字符串的对应方法用法一致。也可以使用循环,配合 in 与 not in 查找 56 | list.index('a', 1, 3) # 左闭右开区间 57 | 58 | # 排序 59 | list.sort(reverse=True) # 默认由小到大排序,添加False参数,则由大到小排列 60 | 61 | # 逆置 62 | list.reverse() 63 | ``` 64 | 65 | ## 三 引用类型-字典 66 | 67 | ### 3.1 字典定义 68 | 69 | 列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。 70 | 71 | ```py 72 | tinydict = { 73 | 'name': 'overnote', 74 | 'code':1, 75 | 'site': 'overnote/python' 76 | } 77 | print (tinydict) # 输出完整的字典 78 | print (tinydict.keys()) # 输出所有键 79 | print (tinydict.values()) # 输出所有值 80 | ``` 81 | 82 | 访问元素: 83 | ```py 84 | dict = {} 85 | dict['one'] = "javascript" 86 | dict[2] = "golang" 87 | print (dict['one']) # 输出键为 'one' 的值,若不存在则报错 88 | print (dict[2]) # 输出键为 2 的值 89 | ``` 90 | 91 | 判断元素是否存在推荐使用get(): 92 | ```py 93 | tinydict = { 94 | 'name': 'overnote', 95 | 'code':1, 96 | 'site': 'overnote/python' 97 | } 98 | tinydict.get("name") # overnote 99 | print(tinydict.get("name1")) # None 100 | print(tinydict.get("name1")) # default 若不存在键,就返回参数给出的默认值 101 | ``` 102 | 103 | ### 3.2 字典常见操作 104 | ```py 105 | dict["key"] # 访问元素 106 | dict.get("key") # 访问元素 107 | dict["key"] = "value" # 修改元素,若key不存在,则新增键值对 108 | del dict["key"] # 删除元素 109 | del dict # 删除字典 110 | dict.clear() # 清空字典 111 | len(dict) # 字段键值对个数 112 | dict.keys() # key列表 113 | dict.values() # 值列表 114 | dict.items() # 将字典转换为列表 [('name', 'overnote'), ('code', 1)] 115 | ``` 116 | 贴士:has_key()可以查看key是否在字典中,该方法在Python3中取消。 117 | 118 | ## 四 补充 119 | 120 | ### 4.1 引用类型-集合 121 | 122 | 集合是无序的,集合中的元素是唯一的,集合一般用于元组或者列表中的元素去重。 123 | ```py 124 | # 定义一个集合 125 | s = set() 126 | ``` 127 | 128 | 常见操作: 129 | ```py 130 | set1 = {1, 2, 4, 5} 131 | 132 | # 添加元素 133 | set1.add(8) 134 | 135 | # 修改元素:把传入的元素拆分,作为个体传入到集合中 136 | set1.update("abcd") 137 | 138 | # 删除元素 pop() 方法会随机删除元素, 139 | set1.remove(22) # 如果没有该元素,则报错 140 | set1.discard(22) # 如果没有该元素,不做任何操作 141 | ``` 142 | 143 | 集合可以进行集合运算 144 | ```py 145 | a = set('abracadabra') 146 | b = set('alacazam') 147 | print(a) 148 | print(a - b) # a 和 b 的差集 149 | print(a | b) # a 和 b 的并集 150 | print(a & b) # a 和 b 的交集 151 | print(a ^ b) # a 和 b 中不同时存在的元素 152 | ``` 153 | 154 | 155 | ### 4.2 值类型-元组 156 | 157 | 元组(tuple)与列表类似,不同之处在于元组是不可变的。 158 | ```py 159 | tuple = ( 'abcd', 786 , 2.23, 'overnote', 70.2 ) 160 | tinytuple = (123, 'overnote') 161 | 162 | print (tuple) # 输出完整元组 163 | print (tuple[0]) # 输出元组的第一个元素 164 | print (tuple[1:3]) # 输出从第二个元素开始到第三个元素 165 | print (tuple[2:]) # 输出从第三个元素开始的所有元素 166 | print (tinytuple * 2) # 输出两次元组 167 | print (tuple + tinytuple) # 连接元组 168 | ``` -------------------------------------------------------------------------------- /01-Python语法/05-函数.md: -------------------------------------------------------------------------------- 1 | ## 一 函数概念 2 | 3 | Python中定义与调用函数的方式: 4 | ```py 5 | def show(): 6 | print('人生苦短,我用Python') 7 | 8 | show() 9 | ``` 10 | 11 | 带参数的函数: 12 | ```py 13 | def show(num1, num2): 14 | print(num1 + num2) 15 | 16 | show(1,3) 17 | ``` 18 | 19 | ## 二 局部变量与全局变量 20 | 21 | 在函数内部定义的变量,其作用范围只位于该函数内,被称为 `局部变量`: 22 | ```py 23 | def show(): 24 | info = 'hello' 25 | print(info) 26 | 27 | show() 28 | print(info) # 报错: info is not defined 29 | ``` 30 | 31 | 在函数外部定义,提供一些函数使用的变量,对这些函数来说,该变量是全局变量: 32 | ```py 33 | info = 'hello' 34 | 35 | def show(): 36 | info = 'world' 37 | print(info) 38 | 39 | show() # world 40 | print(info) # hello 41 | ``` 42 | 43 | 当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值。 44 | 45 | 如果要在函数内部修改全局变量,则需要借助 `global` 关键字的声明: 46 | ```py 47 | info = 'hello' 48 | 49 | def show(): 50 | global info 51 | info = 'world' 52 | print(info) 53 | 54 | show() # world 55 | print(info) # world 56 | ``` 57 | 58 | ## 三 返回值 59 | 60 | return关键字用来为函数返回数据,Python中有多个return不会造成语法错误: 61 | ```py 62 | def create_nums(): 63 | print("---1---") 64 | return 1 # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数 65 | print("---2---") 66 | return 2 67 | print("---3---") 68 | ``` 69 | 70 | Python的return支持返回多个数据,return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据: 71 | ```py 72 | def fn(a, b): 73 | r1 = a//b 74 | r2 = a%b 75 | return r1, r2 # 返回结构类型默认是元组 76 | 77 | result = fn(5, 2) 78 | print(result) # 输出(2, 1) 79 | 80 | # 多返回值可以直接进行拆包 81 | num1, num2 = fn(5, 2) 82 | print(num1) 83 | print(num2) 84 | ``` 85 | 86 | ## 四 参数 87 | 88 | ### 4.1 缺省参数 89 | 90 | 如果在调用参数时,缺省参数的值没有传入,则取其默认值: 91 | ```py 92 | def show(name, age=35): 93 | print("name: %s" % name) 94 | print("age %d" % age) 95 | 96 | show(name="miki") # 在函数执行过程中 age去默认值35 97 | ``` 98 | 注意:带有默认值的参数一定要位于参数列表的最后面。 99 | 100 | ### 4.2 不定长参数 101 | 102 | 参数的数量无法预估,则可以使用不定长参数: 103 | ```py 104 | def fn(a, b, *args, **kwargs): 105 | for key, value in kwargs.items(): 106 | print("key=%s" % value) 107 | 108 | fn(1, 2, 3, 4, 5, m=6, n=7, p=8) # 输出 8 6 7 109 | ``` 110 | 111 | 注意:缺省参数需要放在 *args 后面, 但如果有**kwargs的话,该参数必须是放在最后的。 112 | 113 | ### 4.3 引用传递 114 | 115 | 在Python中,值是靠引用来传递来的。 116 | ```py 117 | info = [1, 2] 118 | 119 | def show(info): 120 | info = [1, 2, 3] 121 | print(info) 122 | 123 | show(info) # [1, 2, 3] 124 | print(info) # [1, 2] 125 | ``` 126 | 127 | 使用id函数可以查看其引用地址: 128 | ```py 129 | info = [1, 2] 130 | 131 | def show(info): 132 | info = [1, 2, 3] 133 | print(id(info)) 134 | 135 | show(info) # 4476436560 136 | print(id(info)) # 4476596304 137 | ``` 138 | 总结: 139 | - Python中函数参数是引用传递(注意不是值传递) 140 | - 对于不可变类型,因变量不能修改,所以运算不会影响到变量自身 141 | - 对于可变类型来说,函数体中的运算有可能会更改传入的参数变量 142 | 143 | ## 五 简单的文件操作 144 | ```py 145 | # 打开一个文件,不存在则新建 146 | f = open('test.txt', 'w') 147 | 148 | # 写入数据 149 | f.write('hello world, i am here!') 150 | 151 | # 读取数据 152 | content = f.read(5) # 最多读取5个数据 153 | print(content) 154 | content = f.read() # 从上次读取的位置继续读取剩下的所有的数据 155 | print(content) 156 | 157 | # 关闭这个文件 158 | f.close() 159 | ``` 160 | 161 | 打开方式: 162 | ``` 163 | r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 164 | w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 165 | a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 166 | rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 167 | wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 168 | ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 169 | r+ 打开一个文件用于读写。文件指针将会放在文件的开头。 170 | w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 171 | a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 172 | rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 173 | wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 174 | ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 175 | ``` 176 | 177 | readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素: 178 | ```py 179 | f = open('test.txt', 'r') 180 | content = f.readlines() 181 | print(type(content)) 182 | 183 | i=1 184 | for temp in content: 185 | print("%d:%s" % (i, temp)) 186 | i += 1 187 | 188 | f.close() 189 | ``` -------------------------------------------------------------------------------- /01-Python语法/07-面向对象-类与对象.md: -------------------------------------------------------------------------------- 1 | ## 一 Python中的面向对象 2 | 3 | ### 1.1 类与对象 4 | 5 | ```py 6 | # class Person2: 旧版定义类方式 7 | # class Person2(): 旧版定义类方式 8 | 9 | # 创建类 10 | class Person(object): 11 | 12 | # 默认初始化方法,系统自动调用,不需要初始化一些数据则可以生路 13 | def __init__(self): 14 | self.surename = "李" 15 | 16 | def hello(self): 17 | print("my surname is %s" % self.surename) 18 | 19 | def say(self): 20 | print("my age is %d" % self.age) 21 | 22 | 23 | # 创建对象 24 | p = Person() 25 | p.hello() 26 | 27 | # 给对象添加新的属性 28 | p.age = 13 29 | p.say() 30 | ``` 31 | 32 | 说明: 33 | - object是Python 里所有类的最顶级父类; 34 | - say是一个实例方法,第一个参数一般是self,表示实例对象本身,self名称也可以任意取名,其意义相当于其他编程语言的this。 35 | 36 | 初始化一个对象时,也可以附带一些参数: 37 | ```py 38 | class Person(object): 39 | 40 | def __init__(self, skill): 41 | self.surename = "李" 42 | self.skill = skill 43 | 44 | # 创建对象 45 | p = Person("唱歌") 46 | print(p.skill) # 唱歌 47 | ``` 48 | 49 | ## 二 魔法方法 50 | 51 | 在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法,比如 `__init__()`。 52 | 53 | `__str__`方法默认返回一个字符串,用来描述对象的信息: 54 | ```py 55 | # 创建类 56 | class Person(object): 57 | 58 | def __init__(self, skill): 59 | self.surename = "李" 60 | self.skill = skill 61 | 62 | def __str__(self): 63 | return "这个人姓 %s,技能是:%s" % (self.surename, self.skill) 64 | 65 | # 创建对象 66 | p = Person("唱歌") 67 | # 当类的实例化对象 拥有 __str__ 方法后,那么打印对象则 调用__str__ 。 68 | print(p) 69 | ``` 70 | 71 | 查看类的文档说明,也就是类的注释: 72 | ```py 73 | print(Person.__doc__) 74 | ``` 75 | 76 | 删除对象时,默认调用 `__del__()`方法: 77 | ```py 78 | class Person(object): 79 | 80 | def __init__(self, skill): 81 | self.surename = "李" 82 | self.skill = skill 83 | 84 | def __del__(self): 85 | print("__del__方法被调用") 86 | 87 | p = Person("唱歌") 88 | del(p) 89 | ``` -------------------------------------------------------------------------------- /01-Python语法/08-面向对象-三大特性.md: -------------------------------------------------------------------------------- 1 | ## 一 三大特性-封装 2 | 3 | 面向对象思想有三大特性:封装、继承、多态。 4 | 5 | 封装:将属性和方法放到一起做为一个整体,然后通过实例化对象来处理,这样隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了。 6 | 7 | 为了更好的封装,还可以对类的属性和方法增加访问权限控制: 8 | ```py 9 | # 在属性名和方法名 前面 加上两个下划线 __ 即成为私有权限 10 | class Master(object): 11 | def __init__(self): 12 | self.kongfu = "古法煎饼果子配方" 13 | def make_cake(self): 14 | print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 15 | 16 | class School(object): 17 | def __init__(self): 18 | self.kongfu = "现代煎饼果子配方" 19 | 20 | def make_cake(self): 21 | print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 22 | 23 | class Prentice(School, Master): 24 | def __init__(self): 25 | self.kongfu = "猫氏煎饼果子配方" 26 | # 私有属性,可以在类内部通过self调用,但不能通过对象访问 27 | self.__money = 10000 28 | 29 | # 私有方法,可以在类内部通过self调用,但不能通过对象访问 30 | def __print_info(self): 31 | print(self.kongfu) 32 | print(self.__money) 33 | 34 | def make_cake(self): 35 | self.__init__() 36 | print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 37 | 38 | def make_old_cake(self): 39 | Master.__init__(self) 40 | Master.make_cake(self) 41 | 42 | 43 | def make_new_cake(self): 44 | School.__init__(self) 45 | School.make_cake(self) 46 | 47 | class PrenticePrentice(Prentice): 48 | pass 49 | 50 | 51 | damao = Prentice() 52 | # 对象不能访问私有权限的属性和方法 53 | # print(damao.__money) 54 | # damao.__print_info() 55 | 56 | 57 | pp = PrenticePrentice() 58 | # 子类不能继承父类私有权限的属性和方法 59 | print(pp.__money) 60 | pp.__print_info() 61 | ``` 62 | 私有属性不能直接访问,所以无法通过第一种方式修改,一般的通过第二种方式修改私有属性的值:定义一个可以调用的公有方法,在这个公有方法内访问修改。 63 | 64 | ## 二 三大特性-继承 65 | 66 | ### 2.1 继承概念 67 | 68 | 在程序中,继承描述的是多个类之间的所属关系。如果一个类A里面的属性和方法可以复用,则可以通过继承的方式,传递到类B里。 69 | 70 | 那么类A就是基类,也叫做父类;类B就是派生类,也叫做子类: 71 | ```py 72 | # 父类 73 | class A(object): 74 | def __init__(self): 75 | self.num = 10 76 | 77 | def print_num(self): 78 | print(self.num + 10) 79 | # 子类 80 | class B(A): 81 | pass 82 | 83 | 84 | b = B() 85 | print(b.num) 86 | b.print_num() 87 | ``` 88 | 89 | ### 2.2 单继承 90 | 91 | 虽然子类没有定义__init__方法初始化属性,也没有定义实例方法,但是父类有。所以只要创建子类的对象,就默认执行了那个继承过来的__init__方法。 92 | 93 | ```py 94 | # 定义一个Master类 95 | class Master(object): 96 | def __init__(self): 97 | # 属性 98 | self.kongfu = "古法煎饼果子配方" 99 | 100 | # 实例方法 101 | def make_cake(self): 102 | print("按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 103 | 104 | 105 | # 定义Prentice类,继承了 Master,则Prentice是子类,Master是父类。 106 | class Prentice(Master): 107 | # 子类可以继承父类所有的属性和方法,哪怕子类没有自己的属性和方法,也可以使用父类的属性和方法。 108 | pass 109 | 110 | # laoli = Master() 111 | # print(laoli.kongfu) 112 | # laoli.make_cake() 113 | 114 | damao = Prentice() # 创建子类实例对象 115 | print(damao.kongfu) # 子类对象可以直接使用父类的属性 116 | damao.make_cake() # 子类对象可以直接使用父类的方法 117 | ``` 118 | 119 | 注意:子类在继承的时候,在定义类时,小括号()中为父类的名字。 120 | 121 | ### 2.3 多继承 122 | 123 | 多继承可以继承多个父类,也继承了所有父类的属性和方法,如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)。 124 | 125 | ```py 126 | class Master(object): 127 | def __init__(self): 128 | self.kongfu = "古法煎饼果子配方" # 实例变量,属性 129 | 130 | def make_cake(self): # 实例方法,方法 131 | print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 132 | 133 | def dayandai(self): 134 | print("师傅的大烟袋..") 135 | 136 | class School(object): 137 | def __init__(self): 138 | self.kongfu = "现代煎饼果子配方" 139 | 140 | def make_cake(self): 141 | print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 142 | 143 | def xiaoyandai(self): 144 | print("学校的小烟袋..") 145 | 146 | # class Prentice(School, Master): # 多继承,继承了多个父类(School在前) 147 | # pass 148 | 149 | # damao = Prentice() 150 | # print(damao.kongfu) 151 | # damao.make_cake() 152 | # damao.dayandai() 153 | # damao.xiaoyandai() 154 | 155 | 156 | class Prentice(Master, School): # 多继承,继承了多个父类(Master在前) 157 | pass 158 | 159 | damao = Prentice() 160 | print(damao.kongfu) # 执行Master的属性 161 | damao.make_cake() # 执行Master的实例方法 162 | 163 | # 子类的魔法属性__mro__决定了属性和方法的查找顺序 164 | print(Prentice.__mro__) 165 | 166 | damao.dayandai() # 不重名不受影响 167 | damao.xiaoyandai() 168 | ``` 169 | 170 | ### 2.4 子类重写父类的同名属性和方法 171 | ```py 172 | class Master(object): 173 | def __init__(self): 174 | self.kongfu = "古法煎饼果子配方" 175 | 176 | def make_cake(self): 177 | print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 178 | 179 | 180 | class School(object): 181 | def __init__(self): 182 | self.kongfu = "现代煎饼果子配方" 183 | 184 | def make_cake(self): 185 | print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 186 | 187 | 188 | class Prentice(School, Master): # 多继承,继承了多个父类 189 | def __init__(self): 190 | self.kongfu = "猫氏煎饼果子配方" 191 | 192 | def make_cake(self): 193 | print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 194 | 195 | 196 | # 如果子类和父类的方法名和属性名相同,则默认使用子类的 197 | # 叫 子类重写父类的同名方法和属性 198 | damao = Prentice() 199 | print(damao.kongfu) # 子类和父类有同名属性,则默认使用子类的 200 | damao.make_cake() # 子类和父类有同名方法,则默认使用子类的 201 | 202 | # 子类的魔法属性__mro__决定了属性和方法的查找顺序 203 | print(Prentice.__mro__) 204 | ``` 205 | 206 | ### 2.5 通过super()调用父类方法 207 | ```py 208 | class Master(object): 209 | def __init__(self): 210 | self.kongfu = "古法煎饼果子配方" # 实例变量,属性 211 | 212 | def make_cake(self): # 实例方法,方法 213 | print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 214 | 215 | 216 | # 父类是 Master类 217 | class School(Master): 218 | def __init__(self): 219 | self.kongfu = "现代煎饼果子配方" 220 | 221 | def make_cake(self): 222 | print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 223 | super().__init__() # 执行父类的构造方法 224 | super().make_cake() # 执行父类的实例方法 225 | 226 | 227 | # 父类是 School 和 Master 228 | class Prentice(School, Master): # 多继承,继承了多个父类 229 | def __init__(self): 230 | self.kongfu = "猫氏煎饼果子配方" 231 | 232 | def make_cake(self): 233 | self.__init__() # 执行本类的__init__方法,做属性初始化 self.kongfu = "猫氏...." 234 | print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) 235 | 236 | def make_all_cake(self): 237 | # 方式1. 指定执行父类的方法(代码臃肿) 238 | # School.__init__(self) 239 | # School.make_cake(self) 240 | # 241 | # Master.__init__(self) 242 | # Master.make_cake(self) 243 | # 244 | # self.__init__() 245 | # self.make_cake() 246 | 247 | # 方法2. super() 带参数版本,只支持新式类 248 | # super(Prentice, self).__init__() # 执行父类的 __init__方法 249 | # super(Prentice, self).make_cake() 250 | # self.make_cake() 251 | 252 | # 方法3. super()的简化版,只支持新式类 253 | super().__init__() # 执行父类的 __init__方法 254 | super().make_cake() # 执行父类的 实例方法 255 | self.make_cake() # 执行本类的实例方法 256 | 257 | 258 | damao = Prentice() 259 | damao.make_cake() 260 | damao.make_all_cake() 261 | 262 | # print(Prentice.__mro__) 263 | ``` 264 | 265 | ## 三 三大特性-多态 266 | 267 | 所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态 ,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。 268 | > 鸭子类型:虽然我想要一只"鸭子",但是你给了我一只鸟。 但是只要这只鸟走路像鸭子,叫起来像鸭子,游泳也像鸭子,我就认为这是鸭子。 269 | 270 | Python的多态,就是弱化类型,重点在于对象参数是否有指定的属性和方法,如果有就认定合适,而不关心对象的类型是否正确。 271 | ```py 272 | class F1(object): 273 | def show(self): 274 | print('F1.show') 275 | 276 | class S1(F1): 277 | def show(self): 278 | print('S1.show') 279 | 280 | class S2(F1): 281 | def show(self): 282 | print('S2.show') 283 | 284 | def Func(obj): 285 | # python是弱类型,即无论传递过来的是什么,obj变量都能够指向它,这也就没有所谓的多态了(弱化了这个概念) 286 | print(obj.show()) 287 | 288 | s1_obj = S1() 289 | Func(s1_obj) 290 | 291 | s2_obj = S2() 292 | Func(s2_obj) 293 | ``` -------------------------------------------------------------------------------- /01-Python语法/09-面向对象-补充.md: -------------------------------------------------------------------------------- 1 | ## 一 类属性 2 | 3 | 对象的属性一般称呼为实例属性,类属性则是类本身所拥有的属性,该属性会被所有的实例对象共享,在内存中只存在一个副本,类似java中的静态成员。 4 | 5 | ```py 6 | class People(object): 7 | name = 'Tom' # 公有的类属性 8 | __age = 12 # 私有的类属性 9 | 10 | p = People() 11 | 12 | print(p.name) # 正确 13 | print(People.name) # 正确 14 | print(p.__age) # 错误,不能在类外通过实例对象访问私有的类属性 15 | print(People.__age) # 错误,不能在类外通过类对象访问私有的类属性 16 | ``` 17 | 通过实例(对象)去修改类属性: 18 | ```py 19 | class People(object): 20 | country = 'china' #类属性 21 | 22 | 23 | print(People.country) 24 | p = People() 25 | print(p.country) 26 | p.country = 'japan' 27 | print(p.country) # 实例属性会屏蔽掉同名的类属性 28 | print(People.country) 29 | del p.country # 删除实例属性 30 | print(p.country) 31 | ``` 32 | 33 | 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。 34 | 35 | ## 二 类方法 36 | 37 | 类方法是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。 38 | ```py 39 | class People(object): 40 | # 私有类属性 41 | __country = 'china' 42 | 43 | #类方法,用classmethod来进行修饰 44 | @classmethod 45 | def get_country(cls): 46 | return cls.__country 47 | 48 | p = People() 49 | print(p.get_country()) #可以用过实例对象引用 50 | print(People.get_country()) #可以通过类对象引用 51 | ``` 52 | 53 | 类方法还有一个用途就是可以对类属性进行修改: 54 | ```py 55 | class People(object): 56 | # 私有类属性 57 | __country = 'china' 58 | 59 | #类方法,用classmethod来进行修饰 60 | @classmethod 61 | def get_country(cls): 62 | return cls.__country 63 | 64 | @classmethod 65 | def set_country(cls,country): 66 | cls.__country = country 67 | 68 | 69 | p = People() 70 | print(p.get_country()) #可以用过实例对象访问 71 | print(People.get_country()) #可以通过类访问 72 | 73 | p.set_country('japan') 74 | 75 | print(p.get_country()) 76 | print(People.get_country()) 77 | ``` 78 | 79 | ## 三 静态方法 80 | 81 | 静态方法需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数,可以通过对象和类来访问。 82 | 83 | ```py 84 | class People(object): 85 | country = 'china' 86 | 87 | @staticmethod 88 | #静态方法 89 | def get_country(): 90 | return People.country 91 | 92 | 93 | p = People() 94 | # 通过对象访问静态方法 95 | p.get_contry() 96 | 97 | # 通过类访问静态方法 98 | print(People.get_country()) 99 | ``` 100 | 101 | ## 四 __new__ 方法 102 | 103 | 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节: 104 | ```py 105 | class A(object): 106 | def __init__(self): 107 | print("这是 init 方法") 108 | 109 | def __new__(cls): 110 | print("这是 new 方法") 111 | return object.__new__(cls) 112 | 113 | A() 114 | ``` 115 | 116 | __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供。 117 | 118 | __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例。 119 | 120 | 有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值。 121 | 122 | -------------------------------------------------------------------------------- /01-Python语法/10-异常.md: -------------------------------------------------------------------------------- 1 | ## 一 异常 2 | 3 | 当Python检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"。 4 | 5 | ```py 6 | print '-----test--1---' 7 | open('123.txt','r') # 此处发生异常,程序崩溃 8 | print '-----test--2---' 9 | ``` 10 | 11 | 异常需要捕获: 12 | ```py 13 | try: 14 | print('-----test--1---') 15 | open('123.txt','r') 16 | print('-----test--2---') 17 | except IOError: 18 | pass 19 | ``` 20 | 21 | try 捕获多个异常: 22 | ```py 23 | try: 24 | print('-----test--1---') 25 | open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常 26 | print('-----test--2---') 27 | print(num)# 如果num变量没有定义,那么会产生 NameError 异常 28 | 29 | except (IOError,NameError): 30 | #如果想通过一次except捕获到多个异常可以用一个元组的方式 31 | 32 | else: 33 | print('没有捕获到异常,真高兴') 34 | ``` 35 | 36 | finally语句可以在异常发生后强制执行: 37 | ```py 38 | import time 39 | try: 40 | f = open('test.txt') 41 | try: 42 | while True: 43 | content = f.readline() 44 | if len(content) == 0: 45 | break 46 | time.sleep(2) 47 | print(content) 48 | except: 49 | #如果在读取文件的过程中,产生了异常,那么就会捕获到 50 | #比如 按下了 ctrl+c 51 | pass 52 | finally: 53 | f.close() 54 | print('关闭文件') 55 | except: 56 | print("没有这个文件") 57 | ``` 58 | 59 | ## 二 异常的传递 60 | 61 | 如果try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递。 62 | 63 | ```py 64 | import time 65 | try: 66 | f = open('test.txt') 67 | try: 68 | while True: 69 | content = f.readline() 70 | if len(content) == 0: 71 | break 72 | time.sleep(2) 73 | print(content) 74 | finally: 75 | f.close() 76 | print('关闭文件') 77 | except: 78 | print("没有这个文件") 79 | ``` 80 | 81 | 如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,那么这个异常会传递到函数B中,如果函数B有异常处理那么就会按照函数B的处理方式进行执行;如果函数B也没有异常处理,那么这个异常会继续传递,以此类推。如果所有的函数都没有处理,那么此时就会进行异常的默认处理,即通常见到的那样。 82 | 83 | ```py 84 | def test1(): 85 | print("----test1-1----") 86 | print(num) 87 | print("----test1-2----") 88 | 89 | 90 | def test2(): 91 | print("----test2-1----") 92 | test1() 93 | print("----test2-2----") 94 | 95 | 96 | def test3(): 97 | try: 98 | print("----test3-1----") 99 | test1() 100 | print("----test3-2----") 101 | except Exception as result: 102 | print("捕获到了异常,信息是:%s"%result) 103 | 104 | print("----test3-2----") 105 | 106 | 107 | 108 | test3() 109 | print("------华丽的分割线-----") 110 | test2() 111 | ``` 112 | 113 | ## 三 异常的抛出 114 | 115 | raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类 116 | ```py 117 | class ShortInputException(Exception): 118 | '''自定义的异常类''' 119 | def __init__(self, length, atleast): 120 | #super().__init__() 121 | self.length = length 122 | self.atleast = atleast 123 | 124 | def main(): 125 | try: 126 | s = input('请输入 --> ') 127 | if len(s) < 3: 128 | # raise引发一个你定义的异常 129 | raise ShortInputException(len(s), 3) 130 | except ShortInputException as result:#x这个变量被绑定到了错误的实例 131 | print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.atleast)) 132 | else: 133 | print('没有异常发生.') 134 | 135 | main() 136 | ``` -------------------------------------------------------------------------------- /01-Python语法/11-模块.md: -------------------------------------------------------------------------------- 1 | ## 一 模块简介 2 | 模块(module)和C语言中的头文件以及Java中的包很类似,在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。 3 | 4 | ```py 5 | import math 6 | 7 | #这样会报错 8 | print sqrt(2) 9 | 10 | #这样才能正确输出结果 11 | print math.sqrt(2) 12 | ``` 13 | 14 | 有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现: 15 | ```py 16 | from 模块名 import 函数名1,函数名2.... 17 | # 如果想一次性引入math中所有的东西,还可以通过from math import *来实现 18 | ``` 19 | 20 | 注意:如果一个文件中有__all__变量,那么也就意味着这个变量中的元素,不会被from xxx import *时导入。 21 | 22 | ## 二 模块定位 23 | 24 | 当你导入一个模块,Python解析器对模块位置的搜索顺序是: 25 | ``` 26 | 当前目录 27 | 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。 28 | 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/ 29 | 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。 30 | ``` 31 | 32 | ## 三 模块制作 33 | 34 | 在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字,如下所示 test.py文件即为一个模块: 35 | ```py 36 | def add(a,b): 37 | return a+b 38 | # 以下是模块作者的测试代码,无需执行,则需要根据__name__变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码 39 | if __name__ == 'main': 40 | print('test..') 41 | ``` 42 | 在另外一个文件调用该模块: 43 | ```py 44 | import test 45 | 46 | result = test.add(11,22) 47 | print(result) 48 | ``` 49 | 50 | ## 四 包:Python中对模块的组织 51 | 52 | 多个模块互有关系,且最终在合作下统一向外提供一些功能,此时可以将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为包。 53 | 54 | __init__.py 控制着包的导入行为,仅仅是把这个包导入,不会导入包中的模块。在__init__.py文件中,定义一个__all__变量,它控制着 from 包名 import *时导入的模块: 55 | ```py 56 | __all__ = ["sendMsg", "receiveMsg"] 57 | print("---1---") 58 | def test(): 59 | print("---2---") 60 | ``` -------------------------------------------------------------------------------- /01-Python语法/12-Python2与Python3.md: -------------------------------------------------------------------------------- 1 | ## 一 python2与python3简介 2 | 3 | Python 2 or Python 3: 4 | - Python 2.x 是早期版本,Python 3.x是当前版本,Python 2.7 (2.x的最终版)于2010年发布后很少有大的更新 5 | - Python 2.x 比 Python3.x 拥有更多的工具库 6 | - 大多数Linux系统默认安装的仍是 Python 2.x 7 | - 版本选择取决于要解决的问题 8 | 9 | 建议选择 Python 2.x 的情况: 10 | - 部署环境不可控,Python版本不能自行选择 11 | - 12 | - 如果选择使用 Python 3.x,需要确定要用的工具库支持新版本。 13 | 14 | ## 二 python2与python3区别 15 | 16 | (1)脚本语言的第一行`#!/usr/bin/python`,只对Linux/Unix用户适用,用来指定本脚本用什么interperter来执行(调用/usr/bin下的python解释器)。有这句后加上执行权限后,可以直接用./执行,不然会出错,因为找不到python解释器。`#!/usr/bin/env` python这种用法是为了防止操作系统用户没有将python装在默认的/usr/bin路径里。当系统看到这一行的时候,首先会到env设置里查找python的安装路径,再调用对应路径下的解释器程序完成操作,该写法可以增强代码的可移植性,推荐这种写法。 17 | 18 | (2)`# -*- coding:utf-8 -*-` `#coding=utf-8` 。如果要在python2的py文件里面写中文,则必须要添加一行声明文件编码的注释,否则python2会默认使用ASCII编码。查看编码方式: 19 | ```py 20 | import sys 21 | print(sys.getdefaultencoding()) 22 | ``` 23 | Python3 最重要的一项改进之一就是解决了 Python2 中字符串与字符编码遗留下来的这个大坑。 24 | 25 | (3)Python2 字符串设计上的一些缺陷: 26 | - 1.使用 ASCII 码作为默认编码方式,对中文处理很不友好。 27 | - 2.把字符串的牵强地分为 unicode 和 str 两种类型,误导开发者 28 | 29 | (4)Python3 改进: 30 | - Python3 把系统默认编码设置为 UTF-8 31 | - 文本字符和二进制数据区分得更清晰,分别用 str 和 bytes 表示。文本字符全部用 str 类型表示,str 能表示 Unicode 字符集中所有字符,而二进制字节数据用一种全新的数据类型,用 bytes 来表示 32 | - Python3 中,在字符引号前加‘b',明确表示这是一个 bytes 类型的对象,实际上它就是一组二进制字节序列组成的数据 33 | - encode 负责字符(unicode)到字节(byte)的编码转换。默认使用 UTF-8 编码准换。 34 | 35 | 注意区分:Unicode和UTF-8的区别(utf-8是为传送unicode字符的一种再编码的方式) -------------------------------------------------------------------------------- /02-并发与网络/01-多进程.md: -------------------------------------------------------------------------------- 1 | ## 一 传统编程的缺陷 2 | 3 | 传统编程的弊端: 4 | ```py 5 | # 必须按照顺序执行,多个任务无法同时在还行 6 | import time 7 | 8 | 9 | def sing(): 10 | for i in range(5): 11 | print("sing: hero") 12 | time.sleep(1) # 每唱一次,等1秒再唱 13 | 14 | 15 | def dance(): 16 | for i in range(5): 17 | print("dance: swan") 18 | time.sleep(1) # 每唱一次,等1秒再跳 19 | 20 | 21 | def main(): 22 | sing() 23 | dance() 24 | 25 | 26 | if __name__ == "__main__": 27 | main() 28 | ``` 29 | 2个任务花费的时间是10秒,如果要边跳边唱,其实2个任务是可以在最长的那个任务完成时全部完成的。 30 | 31 | 实现多任务编程的方式有很多,如:多进程、多线程、协程等。 32 | 33 | ## 二 使用多进程方式实现多任务 34 | 35 | ```py 36 | # 必须按照顺序执行,多个任务无法同时在还行 37 | import time 38 | import multiprocessing 39 | 40 | 41 | def sing(): 42 | for i in range(5): 43 | print("sing: hero") 44 | time.sleep(1) # 每唱一次,等1秒再唱 45 | 46 | 47 | def dance(): 48 | for i in range(5): 49 | print("dance: swan") 50 | time.sleep(1) # 每唱一次,等1秒再跳 51 | 52 | 53 | def main(): 54 | p1 = multiprocessing.Process(target=sing) 55 | p2 = multiprocessing.Process(target=dance) 56 | p1.start() 57 | p2.start() 58 | 59 | 60 | if __name__ == "__main__": 61 | main() 62 | ``` 63 | ## 三 进程的一些操作 64 | 65 | 通过 `htop` 命令可以查看详细的进程列表。 66 | 67 | 注意:使用`kill -9 pid` 杀死主进程后,子进程不会被杀死,此时命令行也会无法正常退出,因为该命令的信号是发给了主进程来执行杀死任务,子进程由于没有父进程,变成了孤儿进程,之后被init进程领养。也就是说杀死主进程后,子进程的父进程称为了init进程。 68 | 69 | 通过 `os.getpid()` 可以获取到当前进程的pid,`os.getppid()`可以获取父进程id。 70 | 71 | ## 四 进程间通信 72 | 73 | 进程之间无法直接进行通信,因为他们是互相独立的应用程序。 74 | 75 | 进程之间要实现通信,常见的方式有:socket等,python中可以使用队列方式实现: 76 | ```py 77 | queue = multiprocessing.Queue(3) 78 | queue.put("111") 79 | queue.put(222) 80 | 81 | # 取数据 82 | res = queue.get() 83 | print(res) 84 | # 判断: q.full() q.empty() 85 | ``` 86 | 87 | ## 五 进程池 88 | 89 | ```py 90 | p = multiprocessing.Pool(3) 91 | ``` 92 | 93 | -------------------------------------------------------------------------------- /02-并发与网络/02-多线程.md: -------------------------------------------------------------------------------- 1 | ## 一 多线程方式实现多任务 2 | 3 | ```py 4 | import time 5 | import threading 6 | 7 | 8 | def sing(): 9 | for i in range(5): 10 | print("sing: hero") 11 | time.sleep(1) # 每唱一次,等1秒再唱 12 | 13 | 14 | def dance(): 15 | for i in range(5): 16 | print("dance: swan") 17 | time.sleep(1) # 每唱一次,等1秒再跳 18 | 19 | 20 | def main(): 21 | t1 = threading.Thread(target=sing) # 创建一个线程对象 22 | t2 = threading.Thread(target=dance) # 创建一个线程对象 23 | t1.start() # 开启线程 24 | t2.start() # 开启线程 25 | 26 | 27 | if __name__ == "__main__": 28 | main() 29 | ``` 30 | 31 | 32 | ## 二 线程相关API 33 | 34 | 通过 `threading.Thread() ` 可以创建线程,`threading.enumerate()` 也可以查看当前所有的线程: 35 | ```py 36 | import time 37 | import threading 38 | 39 | 40 | def sing(): 41 | for i in range(5): 42 | print("sing: hero") 43 | time.sleep(1) # 每唱一次,等1秒再唱 44 | 45 | 46 | def dance(): 47 | for i in range(5): 48 | print("dance: swan") 49 | time.sleep(1) # 每唱一次,等1秒再跳 50 | 51 | 52 | def main(): 53 | 54 | t1 = threading.Thread(target=sing) 55 | t2 = threading.Thread(target=dance) 56 | 57 | t1.start() 58 | t2.start() 59 | 60 | while True: 61 | length = len(threading.enumerate()) 62 | print("当前线程数为:%d" % length) 63 | if length <= 1: 64 | break 65 | time.sleep(0.5) 66 | 67 | 68 | if __name__ == "__main__": 69 | main() 70 | ``` 71 | 72 | ## 三 同步与死锁 73 | 74 | 线程是共享全局变量的,这样就会造成数据的混乱: 75 | ```py 76 | import time 77 | import threading 78 | 79 | # 定义共享的全局变量 80 | num = 0 81 | 82 | 83 | def add100(): 84 | global num 85 | for i in range(100000): 86 | num = num + 0.00001 87 | 88 | 89 | def add1000(): 90 | global num 91 | for i in range(100000): 92 | num = num + 1000 93 | 94 | 95 | def main(): 96 | 97 | t1 = threading.Thread(target=add100) 98 | t2 = threading.Thread(target=add1000) 99 | 100 | t1.start() 101 | t2.start() 102 | 103 | time.sleep(5) 104 | print(num) # 每次输出的结果是不相同的 105 | 106 | 107 | if __name__ == "__main__": 108 | main() 109 | ``` 110 | 111 | 112 | 使用互斥锁实现同步的方案: 113 | ```py 114 | import time 115 | import threading 116 | 117 | # 定义共享的全局变量 118 | num = 0 119 | 120 | 121 | def add100(): 122 | global num 123 | mutex.acquire() # 加锁:若已经加锁,则会直到锁被揭开 124 | for i in range(100000): 125 | num = num + 0.00001 126 | mutex.release() # 解锁 127 | 128 | 129 | def add1000(): 130 | global num 131 | mutex.acquire() # 加锁:若已经加锁,则会直到锁被揭开 132 | for i in range(100000): 133 | num = num + 1000 134 | mutex.release() # 解锁 135 | 136 | 137 | # 创建互斥锁,默认不会上锁 138 | mutex = threading.Lock() 139 | 140 | 141 | def main(): 142 | 143 | t1 = threading.Thread(target=add100) 144 | t2 = threading.Thread(target=add1000) 145 | 146 | t1.start() 147 | t2.start() 148 | 149 | time.sleep(5) 150 | print(num) # 100000001.0 永远不会变 151 | 152 | 153 | if __name__ == "__main__": 154 | main() 155 | ``` -------------------------------------------------------------------------------- /02-并发与网络/03-协程.md: -------------------------------------------------------------------------------- 1 | ## 一 理解协程 2 | 3 | ### 1.1 迭代器 4 | 5 | > 可迭代对象:可以使用for..in..语句进行迭代的对象,如 list、tuple、str 6 | 7 | 判断是否可迭代: 8 | ```py 9 | isinstance(100, Iterable) 10 | ``` 11 | 12 | 让一个对象实现可迭代的方式: 13 | ```py 14 | from collections import Iterable 15 | 16 | 17 | class Students(object): 18 | def __init__(self): 19 | self.names = list() 20 | self.currentNum = 0 21 | 22 | def __iter__(self): # 实现该方法让一个对象可以迭代 23 | return self 24 | 25 | def __next__(self): 26 | if self.currentNum < len(self.obj.names): 27 | ret = self.obj.names[self.currentNum] 28 | self.currentNum += 1 29 | return ret 30 | else: 31 | raise StopIteration 32 | 33 | def add(self, name): 34 | self.names.append(name) 35 | 36 | 37 | arr = Students() 38 | arr.add("aa") 39 | arr.add("bb") 40 | arr.add("cc") 41 | 42 | print("是否可以迭代:", isinstance(arr, Iterable)) 43 | ``` -------------------------------------------------------------------------------- /02-并发与网络/04-Socket编程.md: -------------------------------------------------------------------------------- 1 | ## 一 Socket简介 2 | 3 | ### 1.1 udp 4 | Socket简称套接字,是不同主机间进程通信的方式。 5 | 6 | UDP服务端: 7 | ```py 8 | import socket 9 | 10 | # 创建UDP套接字 11 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 12 | 13 | # 绑定本地信息,不绑定则随机分配 14 | s.bind(('127.0.0.1', 8080)) 15 | 16 | # 接收数据 17 | while True: 18 | data = s.recvfrom(1024) 19 | print(data) 20 | 21 | # 关闭套接字 22 | s.close() 23 | ``` 24 | 25 | UDP客户端: 26 | ```py 27 | import socket 28 | 29 | # 创建UDP套接字:第一个参数代表IPV4,第二个参数代表是UDP还是TCP 30 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 31 | 32 | # 套接字发送数据 33 | num = 1 34 | while True: 35 | data = 'hello' + str(num) 36 | # s.sendto('hello', ('127.0.0.1', 8080)) 37 | s.sendto(data.encode('utf-8'), ('127.0.0.1', 8080)) 38 | num = num + 1 39 | if num == 10: 40 | break 41 | 42 | # 关闭套接字 43 | s.close() 44 | ``` 45 | ### 1.2 TCP 46 | 47 | TCP服务端: 48 | ```py 49 | import socket 50 | 51 | # 创建UDP套接字 52 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 53 | 54 | # 绑定服务器 55 | s.bind(('', 8080)) 56 | 57 | # socket创建的套接字属性默认是主动的,listen变为被动,用来接收客户端信息 58 | s.listen(128) 59 | 60 | # 不断循环接收不同客户端的连接 61 | while True: 62 | # 等待到来 63 | rec_client, rec_addr = s.accept() 64 | print(rec_addr) 65 | 66 | # 接收数据 67 | data = rec_client.recv(1024) 68 | print(data) 69 | 70 | # 发送数据 71 | rec_client.send('accept..'.encode('utf-8')) 72 | 73 | # 关闭套接字 74 | rec_client.close() 75 | 76 | ``` 77 | 78 | TCP客户端: 79 | ```py 80 | import socket 81 | 82 | # 创建TCP 83 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 84 | 85 | # 连接服务器 86 | s.connect(('127.0.0.1', 8080)) 87 | 88 | # 套接字发送数据 89 | num = 1 90 | while True: 91 | data = 'hello' + str(num) 92 | rec = s.send(data.encode('utf-8')) 93 | print(rec) 94 | num = num + 1 95 | if num == 10: 96 | break 97 | 98 | # 关闭套接字 99 | s.close() 100 | ``` -------------------------------------------------------------------------------- /03-Web编程/01-Web服务器实现.md: -------------------------------------------------------------------------------- 1 | ## 一 实现示例 2 | 当用户访问服务器的 不管用户访问什么页面 都返回Helloworld: 3 | ```py 4 | import socket 5 | 6 | def request_handler(client_socket): 7 | """为每个客户进行服务""" 8 | # 接收每个客户的请求报文 9 | 10 | recv_data = client_socket.recv(4096) 11 | if not recv_data: 12 | print("客户端已经断开连接") 13 | client_socket.close() 14 | return 15 | print(recv_data) 16 | # 给客户端回复HTTP响应报文:响应行 + 响应头 +空行 + 响应体 17 | 18 | # 响应行 19 | response_line = "HTTP/1.1 200 OK\r\n" 20 | 21 | # 响应头 22 | response_header = "Server: PythonWebServer1.0\r\n" 23 | 24 | # 响应体 25 | response_body = "Hello world!!!!!" 26 | 27 | # 拼接报文 28 | response_data = response_line + response_header + "\r\n" + response_body 29 | 30 | # 发送 31 | client_socket.send(response_data.encode()) 32 | 33 | # 关闭套接字 34 | client_socket.close() 35 | 36 | if __name__ == '__main__': 37 | # 创建一个服务器套接字 38 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 39 | 40 | # 套接字 地址重用选项 1设置0取消 41 | server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 42 | 43 | # 绑定 44 | server_socket.bind(('', 9999)) 45 | 46 | # 监听 被动套接字 设置已完成三次握手队列的长度 47 | server_socket.listen(128) 48 | 49 | while True: 50 | # 从队列中取出一个客户套接字用以服务 51 | 52 | client_socket, client_addr = server_socket.accept() 53 | # 调用函数 对客户端进行服务 54 | request_handler(client_socket) 55 | 56 | ``` -------------------------------------------------------------------------------- /03-Web编程/02-Python连接数据库示例.md: -------------------------------------------------------------------------------- 1 | ## 一 Py连接MySql示例 2 | ```py 3 | import pymysql 4 | 5 | def main(): 6 | 7 | # 1. 链接数据库 8 | conn = pymysql.connect(host='localhost',port=3306,database='mydb',user='root',password='123456',charset='utf8') 9 | 10 | # 2. 获取游标对象 11 | cursor = conn.cursor() 12 | 13 | # 3. 组织字符串 14 | # sql = """select * from goods where name="%s";""" % find_item_name 15 | # print(sql) 16 | sql = """select * from goods where name="apple";""" 17 | 18 | # 4. 执行查询语句 19 | cursor.execute(sql, [find_item_name]) 20 | 21 | # 5. 显示相应的结果 22 | print(cursor.fetchall()) 23 | 24 | # 6. 关闭 25 | cursor.close() 26 | conn.close() 27 | 28 | if __name__ == "__main__": 29 | main() 30 | ``` 31 | 32 | ## 二 Python连接Redis示例 33 | ```py 34 | import redis 35 | 36 | #使用decode_response指定为true,得到字符串类型 37 | redis_store = redis.StrictRedis(host='127.0.0.1',port=6379,decode_responses=True) 38 | 39 | redis_store.set('name','zs') 40 | 41 | name = redis_store.get('name') 42 | ``` 43 | 44 | ## 三 Python连接MongoDB示例 45 | ```py 46 | 47 | ``` -------------------------------------------------------------------------------- /03-Web编程/03-Flask.md: -------------------------------------------------------------------------------- 1 | ## 一 Flask 简介 2 | 3 | Flask 诞生于 2010 年,是利用 Python 语言基于 Werkzeug 工具箱编写的轻量级 Web 开发框架。 4 | 5 | Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展 Flask-Mail,用户认证 Flask-Login,数据库 Flask-SQLAlchemy),都需要用第三方的扩展来实现。比如可以用 Flask 扩展加入 ORM、窗体验证工具,文件上传、身份验证等。Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL。 6 | 7 | 其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是 Flask 框架的核心。 8 | 9 | 文档地址:http://docs.jinkan.org/docs/flask/ 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 OverNote 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 笔记说明 2 | 3 | 这只是一份最基础的草稿,不推荐阅读! 4 | 5 | 由于Python往往作为大家的第二语言来学习,这里只会对Python的语法做基础的罗列,不会由浅入深的讲解。 6 | 7 | 笔记的重要作者: 8 | - [luckypgirl](https://github.com/luckypgirl) 9 | 10 | ## 资料推荐 11 | 12 | 语法篇: 13 | - [《Python编程快速上手》](https://book.douban.com/subject/26836700/):基础入门 14 | - [《Effective Python》](https://book.douban.com/subject/26709315/):基础补充 15 | - [《流畅的Python》](https://book.douban.com/subject/27028517/):经典代表作,算是基础的加强 16 | - [《Python Cookbook》第3版](https://book.douban.com/subject/26381341/):除了语法外,还详细阐述了并发知识 17 | 18 | Web篇: 19 | - [《Two Scoops of Django》](https://book.douban.com/subject/26578004/) 20 | - [《Flask Web开发实战》](https://book.douban.com/subject/30310340/) 21 | 22 | 爬虫篇 23 | - [《Python网络爬虫权威指南》](https://book.douban.com/subject/33386709/) 24 | 25 | 数据挖掘方向: 26 | - [《数据挖掘导论》](https://book.douban.com/subject/5286107/) 27 | - [《利用Python进行数据分析》](https://book.douban.com/subject/30283996/) 28 | 29 | 深度学习方向: 30 | - [《集体智慧编程》](https://book.douban.com/subject/26348921/) 31 | - [《深度学习入门》](https://book.douban.com/subject/30270959/) 32 | - [《深度学习》](https://book.douban.com/subject/27087503/) 33 | - [《Python深度学习》](https://book.douban.com/subject/30293801/) 34 | - [《Scikit-Learn与TensorFlow机器学习实用指南》](https://book.douban.com/subject/27154347/) 35 | - [《Python深度学习:基于PyTorch》](https://book.douban.com/subject/34873001/) 36 | - [《Python数据科学手册》](https://book.douban.com/subject/27667378/) 37 | - [《Python神经网络编程》](https://book.douban.com/subject/30192800/) 38 | 39 | ## 附 40 | 41 | **OverNote**地址:https://github.com/overnote 42 | **笔者的地址**:https://github.com/ruyuejun 43 | 44 | **OverNote分类**: 45 | - [Golang](https://github.com/overnote/over-golang):详尽的 Go 领域笔记:Go 语法、Go 并发编程、GoWeb 编程、Go 微服务等 46 | - [大前端](https://github.com/overnote/over-javascript):包含 JavaScript、Node.js、vue/react、微信开发、Flutter 等大前端技术 47 | - [数据结构与算法](https://github.com/overnote/over-algorithm):以 C/Go 实现为主记录数据结构与算法的笔记 48 | - [服务端架构](https://github.com/overnote/over-server):分布式与微服务笔记,附 Nginx、Mysql、Redis 等常用服务端技术 49 | - [Python 与机器学习](https://github.com/overnote/over-python):Python 相关笔记,完善中 50 | - [Linux](https://github.com/overnote/over-linux):计算机组成原理、操作系统、计算机网络、编译原理基础学科笔记 51 | - [大数据](https://github.com/overnote/over-bigdata):大数据笔记,完善中 52 | - [flutter](https://github.com/overnote/over-flutter) 53 | -------------------------------------------------------------------------------- /images/python/01-00.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overnote/over-python/4b97764c561da8e703f26a328afce4cc1e8bb12c/images/python/01-00.jpeg -------------------------------------------------------------------------------- /images/python/01-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overnote/over-python/4b97764c561da8e703f26a328afce4cc1e8bb12c/images/python/01-01.png -------------------------------------------------------------------------------- /images/python/01-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overnote/over-python/4b97764c561da8e703f26a328afce4cc1e8bb12c/images/python/01-02.png -------------------------------------------------------------------------------- /images/python/aa-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overnote/over-python/4b97764c561da8e703f26a328afce4cc1e8bb12c/images/python/aa-01.png -------------------------------------------------------------------------------- /images/python/aa-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overnote/over-python/4b97764c561da8e703f26a328afce4cc1e8bb12c/images/python/aa-02.png -------------------------------------------------------------------------------- /数据分析篇/01-数据分析概述.md: -------------------------------------------------------------------------------- 1 | ## 一 数据分析简介 2 | 3 | 数据分析:通过对大量数据进行分析,得出一些结论、规律,以便用于生产、生活、商业。 4 | 5 | 数据分析的流程:提出问题-->收集数据-->分析数据-->获得结论-->可视化成果 6 | 7 | ## 二 数据工程领域中的DIKW体系 8 | 9 | - D:Data (数据),是 DIKW 体系中最低级的材料,一般指原始数据,包含(或不包含)有用的信息。 10 | - I:Information (信息),作为一个概念,信息有着多种多样的含义。在数据工程里,表示由数据工程师(使用相关工具)或者 数据科学家(使用数学方法),按照某种特定规则,对原始数据进行整合提取后,找出来的更高层数据(具体数据)。 11 | - K:Knowledge (知识),是对某个主题的确定认识,并且这些认识拥有潜在的能力为特定目的而使用。在数据工程里,表示对信息进行针对性的实用化,让提取的信息可以用于商业应用或学术研究。 12 | - W:Wisdom (智慧),表示对知识进行独立的思考分析,得出的某些结论。在数据工程里,工程师和科学家做了大量的工作用计算机程序尽可能多地提取了价值(I/K),然而真正要从数据中洞察出更高的价值,甚至能够对未来的情况进行预测,则需要数据分析师。 13 | 14 | ## 三 数据分析工具 15 | 16 | 数据分析平台: 17 | - SAS:SAS(STATISTICAL ANALYSIS SYSTEM,简称SAS)公司开发的统计分析软件,是一个功能强大的数据库整合平台。价格昂贵,银行或者大企业才买的起,做离线的分析或者模型用。 18 | - SPSS:SPSS(Statistical Product and Service Solutions,统计产品与服务解决方案)是IBM公司推出的一系列用于统计学分析运算、数据挖掘、预测分析和决策支持任务的产品,迄今已有40余年的成长历史,价格昂贵。 19 | 20 | 数据分析开发语言: 21 | - R/MATLAB:适合做学术性质的数据分析,在实际应用上需要额外转换为Python或Scala来实现,而且MATLAB(MathWorks公司出品的商业数学软件)是收费的。 22 | - Scala:是一门函数式编程语言,熟练使用后开发效率较高,配合Spark适合大规模的数据分析和处理,Scala的运行环境是JVM。 23 | - Python:Python在数据工程领域和机器学习领域有很多成熟的框架和算法库,完全可以只用Python就可以构建以数据为中心的应用程序。在数据工程领域和机器学习领域,Python非常非常流行。 24 | 25 | ## 四 数据建模 26 | 27 | #### 4.1 大数据分析场景和模型应用 28 | 29 | 数据分析建模需要先明确业务需求,然后选择是 描述型分析 还是 预测型分析: 30 | - 如果分析的目的是描述目标行为模式,就采用描述型数据分析,描述型分析就考虑 关联规则、 序列规则 、 聚类 等模型。 31 | - 如果是预测型数据分析,就是量化未来一段时间内,某个事件的发生概率。有两大预测分析模型, 分类预测 和 回归预测。 32 | 33 | #### 4.2 常见的数据建模分类 34 | 35 | ![](../images/python/aa-01.png) 36 | 37 | **分类**: 38 | - 介绍:是通过已有的训练样本去训练得到一个最优模型,再利用这个模型将输入映射为相应的输出,对输出进行简单的判断从而实现分类的目的,也就具有了对未知数据进行分类的能力。 39 | - 原理:将数据映射到 预先定义的 群组或类。算法要求基于数据 特征值 来定义类别,把具有某些特征的数据项映射到给定的某个类别上。分类并没有逼近的概念,最终正确结果只有一个。 在机器学习方法里,分类属于监督学习。 40 | - 模型:采用 离散预测值 41 | 42 | **回归**: 43 | - 介绍:是基于观测数据建立变量间适当的依赖关系,以分析数据内在的规律,得到响应的判断。并可用于预报、控制等问题。 44 | - 原理:用属性的 历史数据 预测未来趋势。算法首先假设一些已知类型的函数可以匹配目标数据,然后分析匹配后的误差,确定一个与目标数据匹配程度最好的函数。回归是对真实值的一种 逼近预测。 45 | - 模型:采用 连续的预测值 46 | 47 | 分类与回归应用:信用卡申请人风险评估、预测公司业务增长量、预测房价,未来的天气情况。 48 | 49 | 50 | **聚类**: 51 | - 介绍:将相似的事物聚集在一起,不相似的事物划分到不同的类别的过程 52 | - 聚类分析:又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法,同时也是数据挖掘的一个重要算法。 53 | - 原理:在没有给定划分类的情况下,根据信息相似度进行信息聚类,聚类的输入是一组 未被标记的数据,根据样本特征的距离或相似度进行划分。划分原则是保持最大的组内相似性和最小的组间相似性。不同于分类,聚类事先 没有任何训练样本,直接对数据进行建模。聚类分析的目标,就是在相似的基础上收集数据来分类。 在机器学习方法里,聚类属于无监督学习。 54 | - 应用:根据症状归纳特定疾病、发现信用卡高级用户、根据上网行为对客户分群从而进行精确营销等 55 | 56 | **时序模型**: 57 | - 介绍:不管在哪个领域中(如金融学、经济学、生态学、神经科学、物理学等),时间序列(time series)数据都是一种重要的结构化数据形式。在多个时间点观察或测量到的任何事物,都可以形成一段时间序列。时间序列大多都是固定频率的,数据点将根据某种规律定期出现。 58 | - 原理:描述 基于时间或其他序列的 经常发生的规律或趋势,并对其建模。 与回归一样,用已知的数据预测未来的值,但这些数据的区别是 变量所处时间的不同。重点考察数据之间在 时间维度上的关联性。 59 | - 应用:下个季度的商品销量或库存量是多少?明天用电量是多少?今天的北京地铁13号线的人流情况? 60 | 61 | ## 五 常见的数据分析应用场景如下 62 | 63 | 市场营销: 64 | - 营销响应分析建模(逻辑回归,决策树) 65 | - 净提升度分析建模(关联规则) 66 | - 客户保有分析建模(卡普兰梅尔分析,神经网络) 67 | - 购物车分析(关联分析Apriori) 68 | - 自动推荐系统(协同过滤推荐,基于内容推荐,基于人口统计推荐,基于知识推荐,组合推荐,关联规则) 69 | - 客户细分(聚类) 70 | - 流失预测(逻辑回归) 71 | 72 | 风险管理: 73 | - 客户信用风险评分(SVM,决策树,神经网络) 74 | - 市场风险评分建模(逻辑回归和决策树) 75 | - 运营风险评分建模(SVM) 76 | - 欺诈检测(决策树,聚类,社交网络) 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /数据分析篇/02-科学计算工具NumPy-1-数据类型.md: -------------------------------------------------------------------------------- 1 | ## 一 Numpy简介 2 | 3 | Numpy(Numerical Python):提供了一个在Python中做科学计算的基础库,重在数值计算,主要用于多维数组(矩阵)处理的库。用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效的多。本身是由C语言开发,是个很基础的扩展,Python其余的科学计算扩展大部分都是以此为基础。 4 | 5 | Numpy主要功能: 6 | - 高性能科学计算和数据分析的基础包 7 | - ndarray,多维数组(矩阵),具有矢量运算能力,快速、节省空间 8 | - 矩阵运算,无需循环,可完成类似Matlab中的矢量运算 9 | - 线性代数、随机数生成 10 | 11 | Scipy :基于Numpy提供了一个在Python中做科学计算的工具集,专为科学和工程设计的Python工具包。主要应用于统计、优化、整合、线性代数模块、傅里叶变换、信号和图像处理、常微分方程求解、稀疏矩阵等,在数学系或者工程系相对用的多一些,和数据处理的关系不大。 12 | 13 | ## 二 ndarray 14 | 15 | #### 2.1 ndarray简介 16 | 17 | ndarray数组(N Dimension Array)是一个多维的数组对象(矩阵),称为ndarray,具有矢量算术运算能力和复杂的广播能力,并具有执行速度快和节省空间的特点。 18 | 19 | 注意:ndarray的下标从0开始,且数组里的所有元素必须是相同类型 20 | 21 | ndarray拥有的属性: 22 | - ndim属性:维度个数 23 | - shape属性:维度大小 24 | - dtype属性:数据类型 25 | 26 | #### 2.2 ndarray的随机创建 27 | 28 | 通过随机抽样 (numpy.random) 生成随机数据: 29 | ```py 30 | import numpy as np 31 | 32 | # 生成指定维度大小(3行4列)的随机多维浮点型数据(二维),rand固定区间0.0 ~ 1.0 33 | arr = np.random.rand(3, 4) 34 | print(arr) 35 | print(type(arr)) # 36 | 37 | # 生成指定维度大小(3行4列)的随机多维整型数据(二维),randint()可以指定区间(-1, 5) 38 | arr = np.random.randint(-1, 5, (3, 4)) 39 | print(arr) 40 | print(type(arr)) 41 | 42 | # 生成指定维度大小(3行4列)的随机多维浮点型数据(二维),uniform()可以指定区间(-1, 5) 43 | arr = np.random.uniform(-1, 5, (3, 4)) 44 | print(arr) 45 | print(type(arr)) 46 | 47 | print('维度个数: ', arr.ndim) 48 | print('维度大小: ', arr.shape) 49 | print('数据类型: ', arr.dtype) 50 | ``` 51 | 52 | #### 2.3 ndarray的序列创建 53 | 54 | np.array(collection为序列型对象list、嵌套序列对象list of list): 55 | ```py 56 | # list序列转换为 ndarray 57 | lis = range(10) 58 | arr = np.array(lis) 59 | 60 | print(arr) # ndarray数据 61 | print(arr.ndim) # 维度个数 62 | print(arr.shape) # 维度大小 63 | 64 | # list of list嵌套序列转换为ndarray 65 | lis_lis = [range(10), range(10)] 66 | arr = np.array(lis_lis) 67 | 68 | print(arr) # ndarray数据 69 | print(arr.ndim) # 维度个数 70 | print(arr.shape) # 维度大小 71 | ``` 72 | 73 | np.zeros():指定大小的全0数组。注意:第一个参数是元组,用来指定大小,如(3, 4)。 74 | np.ones():指定大小的全1数组。注意:第一个参数是元组,用来指定大小,如(3, 4)。 75 | np.empty():初始化数组,不是总是返回全0,有时返回的是未初始的随机值(内存里的随机值)。 76 | 77 | np.arange() 和 reshape():arange() 类似 python 的 range() ,创建一个一维 ndarray 数组。reshape() 将 重新调整数组的维数。 78 | 79 | ```py 80 | # np.arange() 81 | arr = np.arange(15) # 15个元素的 一维数组 82 | print(arr) 83 | print(arr.reshape(3, 5)) # 3x5个元素的 二维数组 84 | print(arr.reshape(1, 3, 5)) # 1x3x5个元素的 三维数组 85 | ``` 86 | 87 | np.arange() 和 random.shuffle():random.shuffle() 将打乱数组序列(类似于洗牌)。 88 | 89 | ```py 90 | arr = np.arange(15) 91 | print(arr) 92 | 93 | np.random.shuffle(arr) 94 | print(arr) 95 | print(arr.reshape(3,5)) 96 | ``` 97 | 98 | #### 2.4 ndarray的数据类型 99 | 100 | dtype参数:指定数组的数据类型,类型名+位数,如float64, int32 101 | 102 | astype方法:转换数组的数据类型 103 | 104 | ```py 105 | # 初始化3行4列数组,数据类型为float64 106 | zeros_float_arr = np.zeros((3, 4), dtype=np.float64) 107 | print(zeros_float_arr) 108 | print(zeros_float_arr.dtype) 109 | 110 | # astype转换数据类型,将已有的数组的数据类型转换为int32 111 | zeros_int_arr = zeros_float_arr.astype(np.int32) 112 | print(zeros_int_arr) 113 | print(zeros_int_arr.dtype) 114 | ``` 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /数据分析篇/02-科学计算工具NumPy-2-矩阵处理.md: -------------------------------------------------------------------------------- 1 | ## 一 ndarray的矩阵处理 2 | 3 | #### 1.1 ndarray的矩阵运算 4 | 5 | 矢量运算:相同大小的数组间运算应用在元素上。 6 | 7 | 数组是编程中的概念,矩阵、矢量是数学概念。在计算机编程中,矩阵可以用数组形式定义,矢量可以用结构定义! 8 | 9 | ```py 10 | # 矢量与矢量运算 11 | arr = np.array([[1, 2, 3], 12 | [4, 5, 6]]) 13 | 14 | print("元素相乘:") 15 | print(arr * arr) 16 | 17 | print("矩阵相加:") 18 | print(arr + arr) 19 | ``` 20 | 21 | 矢量和标量运算:"广播" - 将标量"广播"到各个元素。 22 | ```py 23 | # 矢量与标量运算 24 | print(1. / arr) 25 | print(2. * arr) 26 | ``` 27 | 28 | #### 1.2 ndarray的索引与切片 29 | 30 | 一维数组的索引与切片(与Python的列表索引功能相似): 31 | ```py 32 | # 一维数组 33 | arr1 = np.arange(10) 34 | print(arr1) 35 | print(arr1[2:5]) 36 | ``` 37 | 38 | 多维数组的索引与切片:`arr[1,1] 等价 arr[1][1]`,`[:] 代表某个维度的数据` 39 | ```py 40 | # 多维数组 41 | arr2 = np.arange(12).reshape(3,4) 42 | print(arr2) 43 | 44 | print(arr2[1]) 45 | 46 | print(arr2[0:2, 2:]) 47 | 48 | print(arr2[:, 1:3]) 49 | ``` 50 | 51 | 条件索引:布尔值多维数组:arr[condition],condition也可以是多个条件组合。 52 | 53 | 注意,多个条件组合要使用 & | 连接,而不是Python的 and or。 54 | 55 | ```py 56 | # 条件索引 57 | 58 | # 找出 data_arr 中 2005年后的数据 59 | data_arr = np.random.rand(3,3) 60 | print(data_arr) 61 | 62 | year_arr = np.array([[2000, 2001, 2000], 63 | [2005, 2002, 2009], 64 | [2001, 2003, 2010]]) 65 | 66 | is_year_after_2005 = year_arr >= 2005 67 | print(is_year_after_2005, is_year_after_2005.dtype) 68 | 69 | filtered_arr = data_arr[is_year_after_2005] 70 | print(filtered_arr) 71 | 72 | #filtered_arr = data_arr[year_arr >= 2005] 73 | #print(filtered_arr) 74 | 75 | # 多个条件 76 | filtered_arr = data_arr[(year_arr <= 2005) & (year_arr % 2 == 0)] 77 | print(filtered_arr) 78 | ``` 79 | 80 | #### 1.3 ndarray的维数转换 81 | 82 | 二维数组直接使用转换函数:transpose() 83 | 84 | 高维数组转换要指定维度编号参数 (0, 1, 2, …),注意参数是元组 85 | 86 | ```py 87 | arr = np.random.rand(2,3) # 2x3 数组 88 | print(arr) 89 | print(arr.transpose()) # 转换为 3x2 数组 90 | 91 | 92 | arr3d = np.random.rand(2,3,4) # 2x3x4 数组,2对应0,3对应1,4对应3 93 | print(arr3d) 94 | print(arr3d.transpose((1,0,2))) # 根据维度编号,转为为 3x2x4 数组 95 | ``` 96 | -------------------------------------------------------------------------------- /数据分析篇/04-可视化工具-matplotlib.md: -------------------------------------------------------------------------------- 1 | ## 一 matplotlib简介 2 | 3 | matplotlib模仿Matlab构建,是当前最流行的Python底层绘图库,主要用来制作可视化的数据图标。 4 | 5 | 安装: 6 | ``` 7 | conda install matplotlib 8 | ``` 9 | 10 | 入门程序: 11 | ```py 12 | from matplotlib import pyplot as plt 13 | 14 | # x轴数据,是一个可迭代对象 15 | x = range(2, 26, 2) # x轴从2开始,每次增加2,最大值为26 16 | 17 | # y轴数据,是一个可迭代对象,绘制的结果是 (2,15),(4,13),(6,14.5)....(24,15) 18 | y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15] 19 | 20 | plt.plot(x, y) 21 | plt.show() 22 | ``` 23 | 24 | 运行结果: 25 | ![](../images/python/aa-02.png) 26 | 27 | 28 | ## 二 matplotlib 简单使用 29 | 30 | #### 2.1 设置生成图片 31 | 32 | ```py 33 | from matplotlib import pyplot as plt 34 | 35 | fig = plt.figure(figsize=(20, 8), dpi=80) 36 | 37 | x = range(2, 26, 2) 38 | y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15] 39 | 40 | plt.plot(x, y) 41 | plt.savefig("./demo.svg") 42 | plt.show() 43 | ``` 44 | 45 | #### 2.2 常用设置 46 | 47 | 设置X轴刻度: 48 | ```py 49 | plt.xticks(x) # 当刻度太密集可以使用列表步长(间隔取值)来解决 plt.xticks(x[::2]) 50 | ``` 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /机器学习篇/01-机器学习初识.md: -------------------------------------------------------------------------------- 1 | ## 一 认识大数据与机器学习 2 | 3 | 机器学习与大数据的关系: 4 | 大数据框架做的事基础的数据存储与统计计算,如果要从大量的数据中心发现和挖掘规律,需要使用机器学习方法,通过机器学习算法结合大量数据,构建机器学习模型,通过模型对现实事件做出预测和判断。 5 | 6 | 大数据4V特征: 7 | - 数据量大:TB-PB-ZB 8 | - 数据种类多 9 | - 结构化数据:Mysql存储 10 | - 非结构化数据:视频/音频等HDFS存储 11 | - 半结构化数据:htm,xml等HDFS存储 12 | - 速度块 13 | - 数据的增长的速度快:TB-PB-ZB 14 | - 数据的处理速度快:大数据 框架解决 15 | - 价值密度低-价值高 16 | - 密度=有价值数据/All 17 | - 机器学习学习算法解决 18 | 19 | 机器学习是人工智能的一个分支,深度学习是机器学习的一种方法或技术。 20 | 21 | 日常生活中的机器学习案例:举起iPhone拍照的时候,自动框出人脸;今日头条的推荐新闻等等。 22 | 23 | 机器学习是一门能够挖掘数据价值与应用的学科,研究的是计算机怎样模拟人类的学习行为,以获取新的知识或技能,并重新组织已有的知识结构使之不断改善自身。简单一点说,就是计算机从数据中学习出规律和模式,以应用在新数据上做预测的任务。 24 | 25 | 总结:机器学习模型Model=数据+算法 26 | 27 | ## 二 机器学习的方向 28 | 29 | - 基于规则的学习:基于专家发现的规则,制定规则,只需要新数据代入规则进行判断即可 30 | - 基于模型的学习:基于模型就可以直接进行预测分析 31 | 32 | 33 | 根据是否有类别标签---监督学习和非监督学习 34 | 35 | 36 | * 监督学习: 37 | 38 | * 分类:预测值是否为连续值,不是连续值的预测的话,是分类 39 | * 回归:是连续值的预测的话,是回归 40 | * 非监督学习: 41 | 42 | * 聚类:通过相似性度量,组内的相似性是极高的,组间的相异性极高的,进行分类 43 | * 降维-通过算法进行降维的话,Z1和Z2的物理含义是不明确的 44 | * 特征选择: 45 | * 从原有的特征中选择比较重要的特征-----X1X2X3====>X1X2 46 | ​ 47 | * 半监督学习 48 | 49 | * 应用场景比较多一些, 50 | 51 | * 半监督学习: 52 | 1.基于聚类的假设 53 | 有类别标记的数据+没有类别标记的数据将有类别标记的数据,去掉标签列所有的数据均没标签,对全部数据进行聚类,聚类之后,有类别标记的数据和没有类别标记的数据,有可能被分到不同的组或簇中,将所有的, 有类别标记的数据,根据机器学习常用的处理方法---投票原则,根据少数服从多数的原则进行表决,将没有带类别标签的数据加上类别标签 54 | 2.利用所有样本进行模型训练 55 | * 强化学习(系统) 56 | * 解决连续决策的问题 57 | * 围棋、无人驾驶汽车 58 | * 迁移学习 59 | 60 | 61 | ## 三 机器学习三要素 62 | 63 | * 机器学习=算法+数据+策略(损失函数) 64 | * 机器学习=模型+算法+策略(损失函数) 65 | * 模型:决策函数、条件概率分布 66 | * 策略:损失函数/目标函数/误差函数 67 | * 01损失---分类问题 68 | * 平方损失---回归问题 69 | * 绝对值损失---分类或回归问题 70 | * 算法: 71 | * 解析解 72 | * 最优解-----梯度下降法或牛顿法 73 | 74 | ## 四 模型选择 75 | 76 | * 模型的泛化性能 77 | * 模型对于新数据的适应能力 78 | * 欠拟合:模型对于训练集和测试集效果都很差 79 | * 产生的原因:模型太过于简单 80 | * 产生的时期:训练模型的初期 81 | * 解决办法: 82 | * 增加多项式的特征项,使得模型变得复杂 83 | * 增加多项式的特征项的次数,使得模型复杂 84 | * 减少正则罚项 85 | * 过拟合:模型对于训练集效果很好,对于测试集效果较差 86 | * 产生的原因:模型过于复杂、训练数据量太少、数据不纯 87 | * 产生的时期:训练模型的中后期 88 | * 解决办法: 89 | * 增加训练数据 90 | * 重新清洗数据 91 | * 增加正则罚项(降低模型的复杂度) 92 | * 模型选择的基本原则-奥卡姆剃刀原则 93 | * 在具有相同泛化误差的模型中,选择较为简单的模型,防止过拟合 94 | 95 | ## 五 机器学习的应用 96 | 97 | 并非所有的问题都适合用机器学习解决(很多逻辑清晰的问题用规则能很高效和准确地处理),也没有一个机器学习算法可以通用于所有问题。 98 | 99 | - 1.分类问题:根据数据样本上抽取出的特征,判定其属于有限个类别中的哪一个。比如: 100 | - 垃圾邮件识别(结果类别:1、垃圾邮件 2、正常邮件) 101 | - 文本情感褒贬分析(结果类别:1、褒 2、贬) 102 | - 图像内容识别识别(结果类别:1、喵星人 2、汪星人 3、人类 4、草泥马 5、都不是)。 103 | - 2.回归问题:根据数据样本上抽取出的特征,预测一个连续值的结果。比如: 104 | - 《美人鱼》票房 105 | - 帝都2个月后的房价 106 | - 3.聚类问题:根据数据样本上抽取出的特征,让样本抱抱团(相近/相关的样本在一团内)。比如: 107 | - google的新闻分类 108 | - 用户群体划分 109 | 110 | 再把上述常见问题划到机器学习最典型的2个分类上: 111 | - 分类与回归问题需要用已知结果的数据做训练,属于“监督学习。 112 | - 聚类的问题不需要已知标签,属于“非监督学习”。 113 | 114 | 综上所述其应用场景有: 115 | - 1.计算机视觉:人脸识别、车牌识别、扫描文字识别、图片内容识别、图片搜索等等。 116 | - 2.自然语言处理:搜索引擎智能匹配、文本内容理解、文本情绪判断,语音识别、输入法、机器翻译等等。 117 | - 3.社会网络分析:用户画像、网络关联分析、欺诈作弊发现、热点发现等等。 118 | - 4.推荐:虾米音乐的“歌曲推荐”,某宝的“猜你喜欢”等等。 119 | 120 | ## 六 机器学习所需要的知识 121 | 122 | - 数学:线性代数,微积分,概率论 123 | - 编程:python,r,julia, 124 | - python 125 | - --------------------------------------------------------------------------------