三元运算
什么是三元运算?
三元运算即三元表达式
三元表达式仅应用于:条件成立返回一个值不成立返回一个值.
示例:
a = 5 b = 7 if a < b: val = a else: val = b print(val)
示例:三元表达式写法
val=a if a>b else b print(val)
文件操作
文件的基本处理形式
- 打开文件
- 操作文件
- 关闭文件
方法参数解析:
# 打开文件 f=open(r'文件的路径',mode='打开文件的模式',encoding='操作文件的字符编码') # 读,写 f.read() f.write('你好!!') #关闭文件 f.close
文件的打开编码格式:
- windows:gbk
- Linux:utf-8
打开文件的模式:r ,w , a ,b(不能单独使用)
- r:只读模式
- 当文件不存在时报错
- w:只写模式
- 当文件不存在时创建文件,当文件存在时清空源文件
- a:加模式
- 当文件不存在时创建文件,当文件存在时光标移动至文件尾
文件的操作模式
文件的读取
- 文本模式 ‘r'
- 二进制模式’rb‘
file = open('file_test','r',encoding='utf-8') data = file.read() print(data) file.close()
file = open('file_test', 'rb') data = file.read() print(data) file.close()
文件的循环读取
file = open('file_test','r',encoding='utf-8') for lien in file: print(lien) file.close()
通过模块获取该文件的字符编码
可使用python第三方工具chardet
安装:
终端下输入:C:\Users\67525>pip3 install chardet
Requirement already satisfied: chardet in d:\mypath\python36\lib\site-packages (3.0.4)
语法:
import chardet f = open('文件操作笔记', 'rb') data = f.read() char = chardet.detect(data) print(char)
文件的写入
- 文本模式写入
- 二进制文本模式写入
file = open('file_xie','w',encoding='utf-8') file.write('你好!!') file.close()
file = open('file_xie', 'wb') file.write('你好'.encode('utf-8')) file.close()
文件的追加写入
- 文本追加写入
- 二进制追加写入
file = open('file_xie','a',encoding='utf-8') file.write('\tworld!') file.close()
file = open('file_xie','ab') file.write('\n人生苦短,我用Python!!'.encode('utf-8')) file.close()
混合操作模式(可读写)
file = open('file_xie','w+',encoding='utf-8') file.write('\n你好 世界!') data = file.read() print(data) file.close()
其他的混合模式w+ ,a+,wb+,ab+,rb+
文件的拷贝
import sys l=sys.argv # 把命令行中解释器后空格分割的所有参数都存成列表 # print(l) src_file_path=l[1] dst_file_path=l[2] # print(src_file_path) # print(dst_file_path) with open(r'%s' %src_file_path,mode='rb') as src_f,\ open(r'%s' %dst_file_path,mode='wb') as dst_f: for line in src_f: dst_f.write(line)
文件都修改
- 通过硬盘修改
- 通过内存修改
import os old_name = 'test' new_name = 'new_%s'%old_name old_str = '月' new_str = '日' old_file = open(old_name,'r',encoding='utf-8') new_file = open(new_name,'w',encoding='utf-8') for lien in old_file: if old_str in lien: lien = lien.replace(old_str,new_str) print(lien) new_file.write(lien) old_file.close() new_file.close() os.replace(new_name, old_name)
函数
函数的定义
什么是函数?
函数即在具备某一个功能的子程序。
为什么要有函数?
解决以下问题:
- 组织结构不清晰,可读性差
- 代码冗余
- 管理维护的难度大,扩展性差
函数使用必须遵守的原则:必须先定义后使用。
语法
def 函数名(): """ 文档描述 """ 代码块
定义函数的三种方式
1.有参函数:参数是函数代码需要在调用时传入参数
def max(x,y): if x > y: return x else: return y
2.无参函数:函数在调用时无需传入参数
def sayshi(): print("hello world!!")
3.空函数:即函数体代码块内容为pass
def func(): pass
函数的调用
如何调用函数?
函数名加括号即可调用函数
def func(x,y):
print(x,y)
func(2,3)
调用函数时需知一下几点
- 函数在调用前必须先定义函数,否则就相当于调用一个不存在的变量
- 定义阶段:只检测语法,不执行函数体代码.
- 调用阶段:根据函数名找到对应的内存地址继而执行函数体内的代码.
函数调用的三种方式:
定义函数:
def max(x,y): if x > y: print(x) else: print(y)
调用方式1.:
max(10,20)
调用方式2:
#2.1
res = max(10,20) print(res)
#2.2 res = max(10,20)*10 print(res)
调用方式3:
def max(x,y): if x > y: return x else: return y res = max(max(10,20),30) print(res)
返回值
为何要有返回值?什么是返回值?
在函数运行结束后,需要返回一个结果给调用者,返回的结果即返回值
取返回值可以使用return.
- 返回值没有类型限制.
- 当函数中出现return则代表函数的结束,函数中可以出现多个return但只返回第一个return的返回值且不会执行return后面的代码
返回值得三种种状态:
- 无返回值:则使用默认的返回值None
def func(): print('hello') res = func() print(res)
- 返回一个值:则返回return后面的值
def func2(x,y): s = x+y return s res = func2(1,2) print(res)
- 返回多个值:返回多个值以逗号分隔,以元组的形式返回
def func3(): return 1,2,3,4 res = func3() print(res)
参数
什么是形参?什么是实参?
形参即形式参数:在函数定义时,括号内的参数
实参即实际参数:在函数调用时,括号内传入的参数
补充:形参与实参只在函数调用时绑定关系,在函数结束后则失去绑定关系。
位置参数:
按照顺序定义的参数,可分为位置形参与位置实参
- 位置形参即在函数定义时,括号内定义的参数
- 位置实现即在函数调用时,括号内传入的参数
# 这里是位置形参 def foo(x,y,z): print(x,y,z) #这里是位置实参 foo(1,2,3)
关键字参数
关键字参数即以key-value的传入的参数称为关键字实参。
- 关键字参数相当于以指名道姓的形式为其传参,这便意味着即使不按照顺序定义,依然能为其传参。
- 关键字参数可以与位置参数混合使用,但必须在默认参数后为其传参
示例:定义函数
def foo(x,y,z): print(x,y,z)
示例:调用函数(传参)
foo(x=1,z=3,y=2)
混合使用:
foo(1,z=3,y=2)
错误示范:
1.缺少参数
foo(1,z=3)
2.为某个参数传入多个值
foo(1,x=1,z=3,y=2)
默认参数
默认参数:即在函数定义时以为其指定值在函数调用时无需传入参数。
- 在函数调用时如果传入参数则使用传入的值,否则使用默认值。
- 在传入参数时,默认参数必须在位置参数的后面
- 默认参数的值应该设置为不可变类型
- 默认参数在函数定义时即固定了,所以无法修改
默认参数的应用:在大多时候一个参数不需要经常变更的时候可以使用默认形参,反正使用位置形参
示例:定义函数
def stu_register(name,age,course,country='CN'): print('姓名:',name) print('年龄:',age) print('课程:',course) print('国籍',country)
使用默认参数:
stu_register('zhansan',18,'Linux')
为默认参数传入值:
stu_register('半藏',18,'python','JP')
可变长度的参数
什么的可变长读的参数?
可变长度的参数即函数的实参个数不固定,实参可以是位置实参或者是关键字实参
def func(name,*args,**kwargs): print(name,args,kwargs)
- *args接收的是位置参数,接收到的参数会以元组的形式赋值给args
- **kwargs接收的是关键字参数,接收到的参数会以字典的形式赋值给kwargs
参数的传入,如果不传入参数接收到的值即为空
func('zxx',18,addr='sx')
如果在实参中的*与**则会吧参数实参中的集合打散
func('zxx',*'123434343',**{'a':1,'b':2}) #执行结果为:zxx ('1', '2', '3', '4', '3', '4', '3', '4', '3') {'a': 1, 'b': 2}
函数的嵌套使用
什么是函数的嵌套?
函数的嵌套定义:即在函数定义在该函数内又定义了其他函数.
函数的嵌套调用:即在函数调用时在该函数内又调用了其他函数.
示例:嵌套定义
#! -*- coding:utf-8 -*- def func1(): print('from func1') def func2(): print('from f2') func2()
示例:函数的嵌套调用
def max1(x,y): if x > y: return x else: return y def max2(x,y,z): res1 = max1(x,y) res2 = max(res1,z) return res2 print(max2(15,9,13))
命名空间与作用域
什么的名称空间?什么是作用域?
名称空间即:存放名字与绑定关系的地方.
名称空间可以分为三类:
- 内置名称空间.:用来存放python解释器自带的名字,在python解释器启动时生效,解释器关闭则失效
- 全局名称空间:文件级别的名字,在文件启动时生效,在文件关闭时失效(可以在文件执行时删除,删除即代表失效)
- 局部名称空间:存放函数内定义的名字(如,函数的参数)在函数被调用时生效函数结束则失效
名称空间的加载顺序:内置名称空间----> 全局名称空间 ---->局部名称空间
名称空间的查找顺序:局部名称空间(当前)--->全局名称空间 --->内置名称空间
限定以名字的代码可用范围这个名字即作用域
作用域可分为两类:
- 全局作用域:全局生效的作用域。
- 在任何顺序都能查找到
- 生命周期长
- 局部作用域:只在局部生效(函数内部)的作用域
- 只在函数内部使用
- 函数结束则该作用域失效
作用域的查找顺序:LEGB
- L:LOCALS 函数内的名称空间
- E:enclosing:上一级的名称空间
- G:global:全局名称空间
- B:builtins:内置名称空间
函数对象:
函数为python中的第一类对象:
- 可以被引用
- 可以作为实参参数传给某个形参.
- 可以作为返回值
- 可以作为容器元素
示例:1
def func(): print("函数可被引用") # func即:函数func的内存地址 f = func f()
示例2:
def func1(): print("from func1") def func2(f): print(f"from {f}") func2(func1)
示例3:
def max(x,y): if x > y: return x else: return y res = max(5,10) print(res)
示例4:
def op_gt(): pass def op_lt(): pass def op_eq(): pass op = { '>':op_gt, '<':op_lt, '=':op_eq }
闭包函数
什么是闭包函数?
闭:即定义在内部的东西。
闭包函数:即定义在函数内部的函数,并且该函数对外部函数作用域中的名字纯在引用关系.
闭包函数的两种形式:
示例1:第一种为国定值
def outer(): name = 'Myuan' def inner(): print(f'hello,{name}') inner() outer()
示例2:第二种通过参数传入使值更加灵活
def outer(name): def inner(): print(f'hello,{name}') inner() outer('Myuan')
装饰器
什么是装饰器?装饰器又有什么作用?
装饰器即在不修改被装饰对象的源代码与调用方式的前提下为其添加新的功能。
装饰器的作用即:在遵循开放封闭原则的前提下为其添加新功能
开放封闭原则:即对添加新功能的程序源码是封闭的而对其扩展性是开放的.
示例:无参装饰器
def outer(func): def inner(*args,**kwargs): res = func(*args,**kwargs) return res return inner()
装饰器语法糖:应该在被装饰对象上单独一行写
import time # 这是装饰器 def outer(func): def inner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print(stop_time-start_time) return res return inner # 这是被装饰对象 @outer def index(): time.sleep(3) print("welcome index page...") index()
装饰器的使用实例:登录认证
import time current_user={ 'username':None, # 'login_time':None } def auth(func): # func=index def wrapper(*args,**kwargs): if current_user['username']: print('已经登陆过了') res=func(*args,**kwargs) return res uname=input('用户名>>: ').strip() pwd=input('密码>>: ').strip() if uname == 'egon' and pwd == '123': print('登陆成功') current_user['username']=uname res=func(*args,**kwargs) return res else: print('用户名或密码错误') return wrapper @auth #index=auth(index) def index(): time.sleep(1) print('welcome to index page') return 122
有参装饰器
有参装饰器即带有参数的装饰器
例子:
import time current_user={ 'username':None, # 'login_time':None } def auth(engine): # engine='file' def auth2(func): # func=index def wrapper(*args,**kwargs): if engine == 'file': if current_user['username']: print('已经登陆过了') res=func(*args,**kwargs) return res uname=input('用户名>>: ').strip() pwd=input('密码>>: ').strip() if uname == 'egon' and pwd == '123': print('登陆成功') current_user['username']=uname res=func(*args,**kwargs) return res else: print('用户名或密码错误') elif engine == 'mysql': print('基于MyQL的认证') elif engine == 'ldap': print('基于LDAP的认证') return wrapper return auth2 @auth('ldap') #@auth2 #index=auth2(index) #index=wrapper def index(): time.sleep(1) print('welcome to index page') return 122 index() # wrapper()
迭代器
什么是可迭代对象?什么是迭代器?
可迭代对象即有内置方法_iter_方法的对象
迭代器对象即可迭代对象执行_iter_方法返回后的结果.
迭代器对象的优缺点:
- 提供了一种不依赖索引的取值方式,更加节省内存空间
- 取值麻烦,只能依次取值,并且是一次性的.
可迭代对象与迭代器对象:
- python内置str,list,tuple,dict,set,file都是可迭代对象
- 可迭代对象执行_inter_后返回的结果就是迭代器对象
示例:字符串为例
s = 'hello world' res = s.__iter__() print(res.__next__()) print(res.__next__()) print(res.__next__()) print(res.__next__())
扩展知识点:
for循环又被称为迭代器循环,使用in 后面必须跟一个可迭代对象.
生成器
什么是生成器?
如果一个函数中包含yield关键字,在调用函数时不会yield关键字后面的的代码,而拿到的返回值就是一个生成器.
扩展点:
生成器本身就是一个迭代器,生成器具有迭代器的特性
生成器的yield关键字:
必须初始化,send方法与next方法功能一致,区别是send方法可以给生成器传值。
示例:
def eat(name): print('%s ready to eat' %name) food_list=[] while True: food=yield food_list # food='骨头' food_list.append(food) #food_list=['泔水','骨头'] print('%s start to eat %s' %(name,food)) dog1=eat('zxx') res1=dog1.send('馒头') print(res1) res2=dog1.send('包子') print(res2)
列表生成式
列表生成式即生成列表的表达式。
例子:
l = [i+1 for i in range(10)]
函数的递归调用
什么是递归函数?
递归函数即函数调用的过程中直接或间接的调用自身.
示例:直接调用
def func(): print('func') func() func()
示例:间接调用
def bar(): print('from bar') foo() def foo(): print('from foo') bar() foo()
函数的递归次数是有限制的可以使用sys模块查看或修改
import sys # 查看 print(sys.getrecursionlimit()) # 修改 sys.setrecursionlimit(1500)
递归分为两个阶段:
- 回溯:在使用归回时必须赋予一个结束条件,否则无限递归
- 递推
在使用递归时必须明确
- 必须明确一个结束条件
- 没递归一次,递归的问题必须减少
- 在Python中没有尾递归优化
递归应用实例:斐波那契数列
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done' fib(10)
匿名函数
匿名函数即没有名字的函数。
定义一个匿名函数使用lambda关键字。匿名函数的函数体一个是一个表达式,该表达式必须要有一个返回值
例子:
numbers = list(range(1, 10)) # print(numbers) print(list(map(lambda x:x*x,numbers)))
应用场景:一般与某些特定的方法配合使用
Python内置函数
内置函数的详细介绍:https://docs.python.org/3/library/functions.html?highlight=built#ascii
模块
什么是模块?
模块即一个功能的集合,在python中一个python文件就是一个模块
模块的导入
- import
- form ...import
- from .. import as ..
模块的导入过程:
- 创建一个名称空间
- 执行模块的对应文件并将产生的名字放入创建好的名称空间中
- 在当前执行文件中拿到该模块名,并将该模块名指向以对应的模块名称空间中
示例:导入模块
import time
示例:只想使用某个模块的某个功能时
from tabulate import tabulate
示例:为模块起别名
from tabulate import tabulate as tab
模块的搜索路径
模块的查找顺序:
- 内存中以加载的模块
- 内置模块
- sys.path路径中包含的模块
补充
sys.path中第一个搜索路径是执行文件的当前路径
包的导入
什么是包?
包即文件夹。当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹
导入包的过程:
- 产生一个该包的名称空间
- 执行包下的_init_文件,并将参生的名字存放于该包的名称空间中
- 在当前执行文件中拿到一个名字,将该名字指向包的名称空间中