python3学习第四周
(1-8)上周知识知识回顾:
1.文件操作
文件操作步骤:
a.打开文件,得到句柄。
b.通过句柄操作文件
c.关闭文件
文件操作:
a.增
b.删
c.改
d.查
文件打开方式:
"r","w","a","r+","w+","a+"
"rb","wb","ab"
用这"w"模式打开文件会把原来同名的文件覆盖。
"r+"读追加模式打开文件。
常用方法:
seek() #位置的跳跃
tell() #打印出位置
truncate() #截断字符
flush() #强制把缓存里的东西写到硬盘
2.字符编码转换
python2.x上程序的默认编码为ascⅡ,python3.x上程序的默认编码为Unicode
Unicode识别GBK,Utf-8识别Unicode,所以在转换之前先把字符转换成Unicode编码格式,然后才能转化为其它编码格式。
字符串编码转换步骤:
a.通过decode()方法把字符串解码成Unicode格式。
b.再通过encode()方法把Unicode格式的字符编码为需要的格式。
3.函数
a.函数定义
def func_name(arg1,arg2):
pass
b.位置参数传参
函数调用时,传入的参数要与形参一一对应,与位置有关。
例如:func_name(1, 2)
b.关键字参数传参
函数调用时,通过给形参赋值要传入的参数,与关键字有关。
例如:func_name(arg2= 2,arg1=1)
c.非固定参数
定义函数时,对需要设置的形参个数不确定。
例如:
def func_name(arg1,arg2,*args):
pass
def func_name(arg1,arg2,*args,**kwargs):
pass
给非固定参数传参:
func_name(1,2,4,5,arg5=7,arg6=8):
args接收N个位置参数,并转换为元组形式。
kwargs接N个收关键字参数,并转换为字典形式。
传参时位置参数必须在关键字参数之前
4.全局变量与局部变量
例如:
name="liu chen" #全局变量
def change_name():
name="wjb" #局部变量
print(name)
a.在子程序中(函数)定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
b.全局变量作用域是整个程序,局部变量作用域是定义该变量的函数。
c.当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用,在其它地方全局变量起作用。
d.字符串、数字这类全局变量是不能用局部变量直接更改的,列表、字典、集合、类这类全局变量是能够用局部变量直接更改的
e.可以用global这个关键字来定义一个全局变量。
例如:
name="liu chen"
def change_name():
global age #定义一个全局变量
name="wjb"
print(name)
5.返回值
def func_name():
return False,24
a.返回值的个数为0,则返回None
b.返回值的个数为1,则返回object
c.返回值的个数为>1,则返回元组(tuple)
d. return 语句代表着函数的结束
if func_name(): #表示函数func_name(),如果有返回值就为真,无返回值就为假。
print(func_name)
res=func_name()
if res[0]: #表示函数func_name()返回元组中的第一分元素为True就为真,否则为假。
print(res[0])
6.递归
定义:如果一个函数在内部调用自己本身,这个函数就是递归函数。
特性:
a.必须有一个明确的结束条件。
b.问题规模每次都应该比上一次递归问题规模有所减少。
c.效率不高。
例如:
def calc(n):
print(n)
if int(n/2)>0:
return calc(int(n/2))
print("->",n)
calc(10)
7.高级函数
定义:一个函数把另一个函数当做参数调用,那么这个函数就叫做高阶函数 。
8.函数式编程
a.函数式编程是没有副作用的(知道输入,肯定知道了输出。)
b.函数式不是指函数
9.迭代器&生成器
列表生成式
列表生成式一次生成所有数据(浪费内存)
a.列表生成式例子:a=[i*2 for i in range(10)]
等价于以下代码
a=[]
for i in range(10)
a.append(i*2)
输出结果为[0,2,4,6,8,10,12,14,16,18]
b.列表生成式作用:简化代码,生成列表。
生成器
a.生成器例子:b=( i*2 for i in range(10))
b.生成器特性:1.只有在调用时生成相应的数据,调用后该数据消失(节省内存)。
2.只记住当前位置(不能取当前位置之前的数据,只能取当前位 置之后的数据)。
3.只有一个__next__()方法取当前位置的下一个值。
4.可以通过for循环取所有数据。
c.把函数改成生成器
1.斐波拉契函数:
def fib(max):
n,a,b=0,0,1
while n<max:
print(b)
a,b=b,a+b
n=n+1
return "done" #异常时打印的内容
#函数执行完毕才能干其它事
2.用斐波拉契函数改成的生成器:
def fib(max): #生成器函数
n,a,b=0,0,1
while n<max:
yield b #程序暂停并返回b(程序执行的状态点)
a,b=b,a+b
n=n+1
return "done" #异常时打印的内容
g=fib(6) #创建生成器函数对象
print(g.__next__()) #g._next_()方法执行生成器函数直到yield暂停
print("=====我干其它的====")#跳出生成器干其它的事
print(g.__next__()) #又回来取生成器生成的下一个数据
for i in f:
print(i)
#把函数改成生成器的作用:
#1.不必等这个生成器执行完,就能干其它事,而且想进就进想出就出
yield作用:设置函数暂停点。
_next_()方法两个连用:
例如g1._next_()
g1._next_()
1.运行生成器函数直到yield停止。
2.从yield暂停点开始执行到yield停止。
通过yield实现在单线程的情况下实现并发运算效果
def consumer(name1): #生成器函数
print("%s准备吃包子了" %name1)
while True:
baozi=yield
print("%s包子来了,被%s吃了"%(baozi,name1))
def producer(name2):
c1=consumer("刘晨")
#创建生成器函数对象
c2=consumer("刘东晨")
#创建生成器函数对象
c3=consumer("郑浩")
#创建生成器函数对象
c1.__next__() #运行生成器函数到yield停止
c1.__next__() #从yield暂停点开始执行到yield停止
c2.__next__() #运行生成器函数到yield停止
c3.__next__() #运行生成器函数到yield停止
print(name2,"开始做包子了")
for i in range(10):
print("做3个包子")
c1.send("韭菜") #给yield传值并从yield暂停点继续运行直到yield停止
c2.send("大蒜") #给yield传值并从yield暂停点继续运行直到yield停止
c3.send("大肉") #给yield传值并从yield暂停点继续运行直到yield停止
producer("温建斌")
_next_()方法两个连用
1.运行生成器函数直到yield停止。
2.从yield暂停点开始执行到yield停止。
send()方法作用
给yield传值并从yield暂停点继续运行直到yield停止
迭代器
可直接作用于for循环的数据类型有以下几种:
1.集合数据内型,如list、tuple、dict、set、str 、byte等
2.生成器,包括生成器和带yield的生成器函数。
可迭代(可循环) 对象:这些可以直接作用于for循环的对象。iterable对象
可以使用isinstance()判断一个对象是否是Iterable对象:
from collections import Iterable
isinstance({},Iterable) #判断字典是否可迭代
生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出stopiterable错误表示无法继续返回下一个值了。
迭代器对象:可以被next()调用并不断返回下一个值的对象。Iterator对象
可以使用isinstance()判断一个对象是否是Iterator(迭代器)对象:
from collections import Iterator
isinstance({},Iterator) #判断字典是否是迭代器对象
生成器都是Iterator(迭代器)对象,但是list、dict、str虽然是iterable但是不是Iterator。
把list、dict、str等iterable变成iterable可以使用iter()函数:
a=[1,2,3]
iter(a)
iterator计算是惰性的,只有在需要返回下一个数据时它才会计算。
小结
凡是可作用于for循环的对象都是Iterable对象(可迭代对象)。
凡是可作用于next()函数的对象都是Iterator对象(迭代器对象),它们表示一个惰性计算的序列。
集合数据内型如list、dict、str等是Iterable对象(可迭代对象)但不是Iterator对象(迭代器对象),不过可以通过iter()函数得到一个Iterator对象(迭代器对象)。
python中的for循环本质上就是通过不断的调用next()函数实现的
10.装饰器
装饰器作用:不改变被装饰函数的代码和调用方式的前提下,给被装饰函数添加功能。
a.装饰器
例子:
import time
def timmer(func):
def warpper(*args,**kwargs):
star_time=time.time()
func()
end_time=time.time()
print("the func run time is %s" %(end_time-star_time))
return warpper
@timmer #装饰器
def
test1():
time.sleep(3)
print("in the test1")
test1()
1.概念:本质是函数(装饰其它函数),为函数添加其它附加功能。
2.原则:a.不能修改被装饰函数的源代码。
b.不能修改被装饰函数的调用方式。
3.实现装饰器知识储备:
a.函数即“变量”
也就是函数体赋值给函数名,函数使用先定义再调用
b.高阶函数
满足以下条件之一就为高阶函数
1.把一个函数名当做实参传给另一个函数
例子:
def bar():
print("in the bar")
def foo(func):
print("in the foo")
foo(bar)
2.返回值中包含函数名
例子:
def foo():
print("in the foo")
return foo
c.嵌套函数
例子:
def foo():
print("in the foo")
def bar():
print("in the bar")
bar()
foo()
嵌套函数定义:在一个函数体中定义一个函数。
高阶函数+嵌套函数=装饰器(即可实现装饰器的效果)
例子:
#高阶函数+嵌套函数实现的装饰器
import
time
def timmer(func):
def deco():
star_time=time.time()
func() #运行test1
end_time=time.time()
print("the func run time is
%s" %(end_time-star_time))
return deco
@timmer #进行这个操作test1=timmer(test1)
def
test1():
time.sleep(3)
print("in the test1")
# test1=timmer(test1)
test1()
#高阶函数+嵌套函数实现的带非固定参数的装饰器
import time
def timmer(func):
def deco(*args,**kwargs):
star_time=time.time()
func(*args,**kwargs)
end_time=time.time()
print("the func run time is
%s" %(end_time-star_time))
return deco
@timmer #等价于test1=timmer(test1)
def
test1():
time.sleep(1)
print("in the test1")
@timmer #等价于test2=timmer(test2)也就是说把deco函数的内存地址给了test2
def
test2(name,age):
time.sleep(1)
print(name,age)
test1()
test2("oil",23) #调用test2相当调用deco函数
decorator 装饰器
装饰器应用实例:网页的登录验证
#给页面添加登录认证,只有登录了才能做其它事情
usnm="xiao"
pswd="123"
def auth(func):
def wrapper(*args,**kwargs):
username=input("username:")
password=input("password:")
if usnm==username and
pswd==password:
print("authentication
has passed,welcome ",username)
res=func(*args,**kwargs)
return res
else:
print("invalid password
or username")
exit()
return wrapper
def index():
print("welcome to index
page")
@auth
def home():
print("welcome to home
page")
return "home!!!!"
@auth
def bbs():
print("welcome to bbs
page")
index()
print(home())
bbs()
应用实例:根据不同的验证方式进行不同的验证
usnm="xiao"
pswd="123"
def auth(auth_type):
def outer_wrapper(func):
def wrapper(*args, **kwargs):
if
auth_type=="local":
username =
input("username:")
password =
input("password:")
if usnm == username and
pswd == password:
print("authentication
has passed,welcome ", username)
res = func(*args,
**kwargs)
return res
else:
print("invalid
password or username")
exit()
elif auth_type=="ldap":
print("是ldap验证!不会!")
return wrapper
return outer_wrapper
def index():
print("welcome to index
page")
@auth(auth_type="local")
def home():
print("welcome to home
page")
return "home!!!!"
@auth(auth_type="ldap")
def bbs():
print("welcome to bbs
page")
index()
print(home())
bbs()
总结:
最终的万能装饰器函数结构为
def timmer(func): #外层函数必须有参数func
def deco(*args,**kwargs): #必须有嵌套函数deco()和非固定参数
func(*args,**kwargs) #必须有func()函数和非固定参数
return deco #必须返回deco()函数的地址
11.内置方法
abs() #取绝对值
all() #可迭代对象中的所有元素为真,则返回True, 空返True否则返回false
any() #可迭代对象中的任一元素为真,则返回True,否则返回false,空返false
bin() #把一个整数转为二进制数
bool() #判断真假
bytearray() #把某个对象转为可更改的字节数组
bytes() #把某个对象转为字节
callable() #判断是否可调用
chr() #返回ascii码对应的对象(数字或者字母或者其它字符)
ord() #返回对象(数字或者字母或者其它字符)码对应的ascii
exec() #运行一段(复杂)代码
例如:
code="for i in range(5):print(i)"
exec(code)
dir() #显示对象的所有方法
eval() #函数只能运行简单的代码
例如:
a=1
eval("a+20")
运行结果为:21
exec() #函数可以动态运行代码段
filter() #过滤掉不符合条件的元素,返回由符合条件元素组成的新list
例如:
res=filter(lamda:n>5,range(10))
for i in res:
print(i)
输出:6,7,8,9
map() #根据提供的函数对指定序列做映射(把传入的数处理后返回,python3中返回迭代器)
例如:
res=map(lambda n:n*2,range(2))
for i in res:
print(i)
输出:0,2
divmod() #返回商和余数
例如:
divmod(5,2)
返回(2,1)
enumerate() #顺序返回对象的索引及对象
例如:
enumerate([a,b,c])
返回(0,a), (1,b) ,(2,c)
formate() #格式化输出字符串
frozenset() #返回一个不可变的集合
globals() #以字典形式返回当前位置的全部全局变量
hash() #用于获取一个对象的哈希值
help() #查看帮助
hex() #把一个整数转为十六进制数
id() #返回内存地址
input() #接收用户输入并转换为字符串
int() #把一个字符串或者数字转换成整型
instance() #判断一个对象是否是某个类型
iter() #生迭代器(转化成迭代器)
len() #返回对象的长度或者项目(元素)个数
list() #把对象转化为列表
local() #以字典的形式返回当前位置的所有局部变量
long() #将字符串或者数字转为长整型
max() #返回给定参数的最大值
memoryview() #返回给定参数的内存查看对象
min() #返回给定参数的最小值
next() #返回迭代器的下一个项目(元素)
oct() #将一个整数转换为八进制的字符串
open() #打开文件,并创建一个file对象
pow() #返回x的y次方
property() #在新式类中返回属性值
range() #创建一个整数列表,一般用在for循环中
reduce() #函数会对参数序列中元素进行累积(计算列表中元素之和)
例如:
reduce(lambda x, y: x+y, [1,2,3,4,5])
结果:15
repr() #讲对象转化为供解释其读取的形式
reverse() #反向列表中的元素
round() #保留到小数点某一个位
set() #将对象转成集合
slice() #返回切片对象
sorted() #对可迭代的对象进行排序
staticmethod 返回函数的静态方法
类可以不用实例化就可以调用该方法 C.f(),当然也可以实例化后调用 C().f()
sun() #求和
super() #用于调用父类(超类)的一个方法
tuple() #将对象转换为元组
str() #把对象转成字符串
type() #判断对象的类型
vars() #以字典的形式返回对象的属性和属性值
zip() #将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
(相当于拉链式拼接)
例如:
a = [1,2,3]
b = [4,5,6]
zipped = zip(a,b)
结果:[(1, 4), (2, 5), (3, 6)]
__import__() #用于动态加载类和函数
12.Jison & pickle数据序列化
json序列化和反序列化
json序列化和反序列化概念:
json序列化是将python对象编码成json字符串。
json反序列化是将json字符串解码为python对象。
json序列化和反序列化作用:
1.只能对简单的数据进行序列化和反序列化,如列表,字典,元组,字符串等
2.可以实现是把内存中的数据存到文件中,json反序列化是把存到文件中的数据读出来存到内存中,最终实现程序的挂起和恢复。
json序列化
import json
info={"name":"zhang","age":25}
f=open("test.text","w")
f.write(json.dumps(info)) #json序列化
f.close()
json反序列化
import json
f=open("test.text","r")
data=json.loads(f.read()) #json反序列化
print(data["age"])
f.close()
json.dumps() #将python对象编码成json字符串
json.loads() #将json字符串解码为python对象
json的序列化和反序列化只能对简单的数据进行,如列表,字典,元组,字符串等
文件中只能存字符串或者二进制码,所以存列表,字典,元组,字符串等须把它们转换为字符串或者二进制码。
json作用就是实现不同程序平台之间数据的交互
xml 作用就是实现不同程序平台之间数据的交互
pickle序列化和反序列化
pickle序列化和反序列化概念:
pickle序列化将python对象编码成pickle二进制码
pickle反序列化将pickle二进制解码成python对象
pickle序列化和反序列化作用:
1.可对任意数据可以进行序列化和反序列化,如函数等
pickle序列化
import pickle
def sayhi(name):
print("hello",name)
info={"name":"zhang","age":25,"func":"sayhi"}
f=open("test.text","wb")
f.write(pickle.dumps(info)) #pickle序列化
f.close()
pickle序列化2
import pickle
def sayhi(name):
print("ni hao",name)
info={"name":"zhang","age":23,"func":sayhi}
f=open("test3.text","wb")
pickle.dump(info,f) #等价于f.write(pickle.dumps(info))#pickle序列化
f.close()
pickle 可以把python中的任意类型数据序列化
pickle反序列化
import pickle
def sayhi(name): #pickle反序列化需要把sayhi函数复制过来
print("ni hao",name)
data=open("test2.text","rb")
info=pickle.loads(data.read()) #pickle反序列化
print(info["func"]("刘东"))
data.close()
pickle反序列化2
import pickle
def sayhi(name):
print("ni hao",name)
info={"name":"zhang","age":23,"func":sayhi}
f=open("test3.text","wb")
pickle.dump(info,f) #等价于f.write(pickle.dumps(info))#pickle反序列化
f.close()
13.软件目录结构规范化
Foo项目
1.bin/:存放项目的一些可执行文件,当然可以起名script/之类。
2.conf/:
3.foo/:或者core/:存放项目的所有源代码。(1)源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2)其子目录tests/存放单元测试代码;(3)程序的入口最好命名为mai.py。
4.logs/:
5.docs/:存放一些文档
6.setup.py:安装、部署、打包的脚本。
7.requirements.text:存放软件依赖的外部python包列表。
8.README:项目说明文件。
如何在atm中调用core包中main文件中的函数或者方法
import os
import sys
print(__file__) #__file__获取当前文件的相对路径
print(os.path.abspath(__file__))
#os.path.abspath(__file__)获取当前文件的绝对路径并打印出
print(os.path.dirname(os.path.abspath(__file__)))#获取当前文件上一级目录的绝对路径并打印出
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))#获取当前文件上上一级目录的绝对路径并打印出
base_dirname=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dirname) #把这个绝对路径添加到系统环境变量中
from
conf import setting
from core import main
main.login()
14.作业:ATM项目开发
模拟实现一个ATM+购物商城程序
1.额度15000或者自定义
2.实现购物商城,买东西加入购物车,调用信用卡接口结账
3.可以提现,手续费5%
4.支持多账户登录
5.支持账户间转账
6.记录每月消费流水
7.提供还款接口
8. ATM记录操作日志
9.提供管理接口,包括添加账户、用户额度、冻结账户等
10.用户认证用装饰器