## 简介
### python是什么
> 编程语言,上手快功能强大,`模块多`,`第三方模块多`
> 模块包括 `数据库` `web` `文件处理`
### 优缺点
> 简单,基础库,第三方库多,提高`工作效率`
> 缺点,解释型语言`效率不及` 编译语言
### python应用场景
> 1 豆瓣等都是python开发
> 2 应用场景 `web开发` `自动化运维` `数据分析` `机器学习`
## Install&per
### Install
* win install
[python_install](https://www.python.org/downloads/)
* mac python installation via package manager
```
brew install python
```
### Text
`PyCharm`, a great advanced IDE. Students can get the license for free.
`Sublime`, awesome customizable text editor
`Atom`, similar to Sublime, developed by Github
`Vim`, advanced text editor, on a holy war with emacs
### Package manager
Python - `pip`
Java - `mvn`
JavaScript - `npm`
```
pip --version
pip install pytest
pip list
```
### Jupyter
> The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text. Uses include: data cleaning and transformation, numerical simulation, statistical modeling, data visualization, machine learning, and much more.
```
pip install jupyter
jupyter --version
#lunch
jupyter notebook
```
* 操作
```
# 新建
shift+enter
# 执行
control+enter
```
## 查看帮助文档等
```
# 查看字符串对象帮助文档
help(str)
# 查看字符串对象属性和方法
dir(str)
# 查看字符串对象文档
str?
```
## 变量
## 运算符
## 流程控制
### 条件控制
* 1 输入一个数判断和10之间的大小关系
* `>10`
* `<10`
* `==10`
```python
a = int(input("Please enter: "))
if a > 10:
print('a > 10')
elif a == 10:
print('a == 10')
else:
print('a < 10')
```
### 循环控制
* 2 for循环遍历列表
```python
strlist = ['hello','viviwong','.com']
for s in strlist:
print(s)
```
* 3 for循环迭代数字列表 0-9
```python
for a in range(10):
print(a)
```
* 4 while循环遍历100-10
```python
w = 100
while w > 10:
print(w)
w -= 10
```
## 异常处理
### 异常
> 不符合预期的用户操作或数据输入,程序会出现异常,处理异常保证程序稳定性
* 5 文件没找到报异常
```python
filename = input("Enter file path:")
f = open(filename)
print(f.read())
```
* 常见异常
* `NameError`
* `SyntaxError`
* `IndexError`
* `KeyError`
* `ValueError`
* `AttributeError`
```python
`NameError` 未定义变量
`SyntaxError` 语法错误
`IndexError` 序列索引超过范围
`KeyError` 字典key不存在
`ValueError` 传入无效参数
`AttributeError` 对象属性不存在
```
### 异常处理
* 异常处理代码格式
```python
try:
可能抛异常的代码
except: 异常类型名称:
处理代码
except: 异常类型名称:
处理代码
finally:
无论如何都执行的代码
```
* 6 文件读取异常处理
```python
filename = input("Enter file path:")
try:
f = open(filename)
print(f.read())
f.close()
except FileNotFoundError:
print("File not found")
finally:
print('我执行了')
```
## 模块和包
> import引入`模块` 模块中的`函数` `类`到代码中
* 7 python默认模块搜索路径,当前目录及系统中python模块的主要安装目录
```python
import sys
sys.path
```
* 模块
* `模块:` 每一个`x.py`都是一个`python模块`
* `包:` 目录`vivi`里面有一个`__init__.py`那么`vivi`文件夹就是一个包
* 导入包里面的模块 导入模块里面的方法
* 8 模块导入
```python
from 包 import 模块
from 模块 import 方法
```
## __main__
* 9 作为模块导入
```python
# 作为模块导入
作为模块导入
if __name__ == '__main__':
```
* 10 作为代码执行
```python
作为模块导入
if __name__ == '__main__':
pass
# 作为代码执行
# 作为代码执行
```
## 四种数据结构 list tuple set dict
### list
> 有序可修改
* 11 list
```
courses = ['Linux', 'Python', 'Vim', 'C++']
courses,type(courses)
courses[0]
courses.append('PHP')
```
### tuple
> 有序不可修改
* 12 tuple
```
courses = ('C++', 'Cloud', 'Linux', 'PHP')
courses,type(courses)
courses[0]
courses.append('PHP')
```
### set
> 无序不重复
* 13 set
```
courses = {'Linux', 'C++', 'Vim', 'Linux'}
courses,type(courses)
'Linux' in courses
```
### dict
> 无序的键值对
* 14 dict
```
coursesdict = {'class1':'Linux', 'class2':'Vim'}
courses,type(courses)
coursesdict['class1']
```
## function
* 15函数
```
def char_count(str, char):
return str.count(char)
result = char_count('hello viviwong','i')
```
## oop
* 抽象
* 封装
* 继承
* 多态
* 16 oop
```
class Animal(object):
def __init__(self, name):
self._name = name
def get_name(self):
return self._name
def set_name(self, value):
self._name = value
# 每个动物发出的声音不一样,pass直接略过
def make_sound(self):
pass
```
## 文件处理
> 文件处理解决的问题,数据`持久化`和获取`配置`
* 17 file
```
filename = input('Enter the file name: ')
with open(filename) as file:
count = 0
for line in file:
count +=1
print(line)
print('Lines:',count)
```
## python高级特性
### 简介
> python的有很多高级用法,可以极大的提高编程效率和代码质量
## lambda
> 匿名函数 lambda
> 通常返回值不需要使用return
> 通常用在需要传入`函数`作为参数的地方
> 并且函数只在这个地方使用,
> 匿名函数作为`参数`传递进去
* 18 匿名函数
* 定义匿名函数实现倍增
* 使用匿名函数
```python
# 定义匿名函数
double =lambda x: x*2
# 使用匿名函数
double(5)
```
## 切片slice
> 获取序列 (list tuple)或字符串的一部分
> 切片格式 `序列[起始index:结束index]`
* 19 列表切片
* 定义列表
* 切片截取部分正切 负切 全部
```python
# 正切
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
letters[1:3]
# 下标对应关系
0 1 2 3 4 5 6
a b c d e f g
-7 -6 -5 -4 -3 -2 -1
# 负切
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
letters[1:-4]
letters[:4]
letters[4:]
# 复制
copy = letters[:]
```
## 列表解析list comprehension
> 列表解析(列表推导),优雅的方式操作列表元素
* 20 列表解析
* 列表1-10
* 使用列表解析挑出列表中所有的偶数
* 使用列表解析所有元素平方
```python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[x for x in numbers if x % 2 == 0]
[x * x for x in numbers]
```
> python中高阶函数有 `map` `filter` `lambda`
> 高阶函数,指可以把函数作为参数传入,并利用传入的函数对数据进行处理的函数
* 使用高阶函数
* filter实现找偶数
* map实现元素平方
```python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# filter(参数1,参数2)
# 参数1为函数,参数2为待处理的数据
f = filter(lambda x: x % 2 == 0, numbers)
for ff in f:
print(ff)
# map(参数1,参数2)
# 参数1为函数,参数2为待处理的数据
m = map(lambda x: x * x, numbers)
for mm in m:
print(mm)
```
> 使用高阶函数增加函数调用开销,时空效率不如使用列表解析
## 字典解析 dict comprehension
> 同列表解析处理对象为字典
* 21 字典解析
* 字典 {'a': 1, 'b': 2, 'c': 3}
* 字典解析 实现 值平方
```python
d = {'a': 1, 'b': 2, 'c': 3}
{k:v*v for k, v in d.items()}
```
## 迭代器
> 迭代(遍历),一个一个读取操作对象叫迭代(遍历)
> 可迭代(Iterable)对象,能用for...in...迭代的对象
> 迭代器(Iterator),能用next函数不断获取它的下一个值,直到迭代器返回`StopIteration`异常,所以可迭代对象都可以通过`iter`函数获取他的迭代器
* 可迭代&迭代器
* 列表letter 元素 a b c
* 使用for in 遍历,说明letter是可迭代对象
* 使用iter函数作用于letter,结果就是迭代器
* 然后使用next函数作用迭代器
* 22 迭代器
```python
# 可迭代
# letter就是可迭代对象
letters = ['a', 'b', 'c']
for letter in letters:
print(letter)
# 迭代器
letters = ['a', 'b', 'c']
# it就是迭代器
it = iter(letters)
next(it)
next(it)
next(it)
next(it)
```
> 可迭代对象其实是实现了`__iter__`和`__next__`两个魔术方法,`iter`与`next`函数实际上调用的就是这两个魔术方法
* 以上例子背后实现是这样的
```python
letters = ['a', 'b', 'c']
# 使用iter(序列)将序列(可迭代对象)变成迭代器
it = letters.__iter__()
it.__next__()
it.__next__()
it.__next__()
it.__next__()
```
> 能被`for`循环的都是`可迭代对象`
> 能被`next()`函数获取下一个值的就是`迭代器`
## 生成器
> 生成器首先是迭代器
> 迭代器和生成器都只能被迭代一次
> 每次迭代的元素不像列表元素已经存在内存中
> 而是每次迭代生成一个元素
* 23 创建生成器并迭代
* 创建1-4生成器 元素平方
* 迭代
* 再次迭代
* 创建1-4生成器
* 使用next()不断访问他的下一个元素
```python
g = (x**x for x in range(1, 4))
for x in g:
print(x)
# 再次迭代没有任何输出
for x in g:
print(x)
g = (x for x in range(1, 4))
next(g)
next(g)
next(g)
next(g)
```
> 生成器元素动态生成,当迭代对象元素多时,使用生成器节约内存
> 生成器是一个迭代器所以可以使用`next()`函数
## 装饰器
> 为函数添加额外功能不影响函数主体功能
> 装饰器实现的基础 函数可以作为参数传递给另一个函数,也可以作为另一个函数的返回值
* 装饰器结构
```
包裹装饰器函数(被修饰的函数):
decorator(非关键词收集,关键词收集):
装饰器内容
return 被修饰函数(非关键词收集,关键词收集)
return decorator
```
* 24 装饰器记录函数调用日志
* 函数 add()求两个数的和
* log()函数里面包裹装饰器记录函数调用时间
```python
from datetime import datetime
# 定义装饰器日志函数
def log(func):
def decorator(*args, **kwargs):
print('Function ' + func.__name__ + ' has been called at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
return func(*args, **kwargs)
return decorator
# 使用装饰器
@log
def add(x, y):
return x + y
add(1, 2)
```
> `@`是python提供的语法糖
> 语法糖计算机语言中添加的某种语法
> 这种语法对语言功能没有影响,更方便程序员使用
> `*arg`和`**kwargs`都是收集参数
> `*arg`非关键词收集,是一个元祖
> `**kwargs`非关键词收集,是一个字典
> 一起用表示收集函数的所有参数
* 以上效果等价于
```python
def add(x, y):
return x + y
add = log(add)
add(1, 2)
```
* 这个时候查看使用装饰器后的函数名
```python
add.__name__
```
> 用log装饰完后,add已经不是原来的函数名了
* 使用函数工具`wraps()`
```python
from datetime import datetime
from functools import wraps
def log(func):
# 添加报错
@wraps(func)
def decorator(*args,**kwargs):
print('function '+func.__name__+" has been called "+datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
return func(*args,**kwargs)
return decorator
@log
def add(x,y):
return x+y
add(6,9)
add.__name__
```