文章目录

  • 可迭代、迭代器
  • 生成器
  • 装饰器
  • 借助闭包实现装饰器
  • 装饰器的函数带参数,并且实现函数代表原函数
  • 借助参数实现装饰器选择调用
  • 多个装饰器原理
  • 结果
  • 常见模块和内置函数
  • calendar日历
  • os
  • time
  • random
  • JSON
  • CSV
  • lambda表达式(匿名函数):
  • map
  • reduce
  • filter


可迭代、迭代器

  • 可迭代协议:可以被迭代要满足的协议就叫做可迭代协议。即内部有__iter__方法
    iterable:可迭代的------对应的标志
    一个一个取值,就像for循环一样取值叫迭代
    字符串,列表,元组,集合,字典都是可迭代的
  • 迭代器协议:内部实现了__iter__,__next__方法
    迭代器大部分都是在python的内部去使用的,我们直接拿来用就行了
    迭代器的优点:如果用了迭代器,节约内存,方便操作
  • 可迭代和迭代器的异同
    异:迭代器内部多实现了一个__next__方法
    同:都可以用for循环;
    Iterable 判断是不是可迭代对象
    Iterator 判断是不是迭代器

生成器

  • 生成器的本质:就是一个迭代器
    1.生成器函数:使用yield语句而不是return语句返回结果
    2.生成器表达式:类似于列表推倒式,就是把列表推导式的 [] 改为了 ()

装饰器

有时你需要在不改变源代码的情况下修改已经存在的函数。常见的例子是增加一句调试声明,以查看传入的参数。这里需要用到装饰器
装饰器实质上是一个函数。 它把一个函数作为输入并且返回另外一个函数。

借助闭包实现装饰器

import time

def timmer(f):    #装饰器函数
    def inner():
        start = time.time()
        ret = f()       #被装饰的函数,ret接受函数返回值'成功属于你'
        end = time.time()
        print(end - start)
        return ret
    return inner

@timmer         #语法糖 @装饰器函数名
def func():     #被装饰的函数
    time.sleep(0.01)
    print('星光不负赶路人')
    return '成功属于你'
# func = timmer(func)  #语法糖相当于这个,func即inner
print(func.__name__)
print(func.__doc__)
ret = func()   #inner(),此时ret接受函数返回值'成功属于你'
print(ret)

装饰器的函数带参数,并且实现函数代表原函数

from functools import wraps
def wrapper(func):  #func = holiday
    @wraps(func)
    def inner(*args,**kwargs):
        print('在被装饰的函数执行之前做的事')
        ret = func(*args,**kwargs)
        print('在被装饰的函数执行之后做的事')
        return ret
    return inner

@wrapper   #holiday = wrapper(holiday)
def holiday(day):
    '''这是一个放假通知'''
    print('奋斗了%s天'%day)
    return '你还不够成功'

print(holiday.__name__)
print(holiday.__doc__)
ret = holiday(100)   #inner
print(ret)

借助参数实现装饰器选择调用

#带参数的装饰器
import time

def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start = time.time()
                ret = func(*args,**kwargs)
                end = time.time()
                print(end-start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer

@timmer_out(False)    #wahaha = timmer(cg)
def cg():
    time.sleep(0.1)
    print('成功')

@timmer_out(True)
def fd():
    time.sleep(0.1)
    print('奋斗')

cg()
fd()

多个装饰器原理

#多个装饰器装饰一个函数
def wrapper1(func):
    def inner1():
        print('wrapper1 ,before func')
        ret = func()
        print('wrapper1 ,after func')
        return ret
    return inner1

def wrapper2(func):
    def inner2():
        print('wrapper2 ,before func')
        ret = func()
        print('wrapper2 ,after func')
        return ret
    return inner2

@wrapper2
@wrapper1
def f():
    print('星光不付赶路人')
    return '自控力'

print(f())

结果

wrapper2 ,before func
wrapper1 ,before func
星光不付赶路人
wrapper1 ,after func
wrapper2 ,after func
自控力

常见模块和内置函数

calendar日历

import calendar
#获取一年的日历字符串
cal = calendar.calendar(2019)

# isleap: 判断某一年是否闰年
calendar.isleap(2000)

# month() 获取某个月的日历字符串
# 格式:calendar.month(年,月)
m3 = calendar.month(2019, 9)

# monthrange() 获取一个月的周几开始即和天数
# 格式:calendar.monthrange(年,月)
# 返回值:元组(周几开始,总天数)
# 注意:周默认 0 -6 表示周一到周天
w,t = calendar.monthrange(2019, 3)

# monthcalendar() 返回一个月每天的矩阵列表
# 格式:calendar.monthcalendar(年,月)
# 返回值:二级列表
# 注意:矩阵中没有天数用0表示
m = calendar.monthcalendar(2018, 3)

# prmonth() 直接打印整个月的日历
# 格式:calendar.prmonth(年,月)
# 返回值:无
calendar.prmonth(2018, 3)

# weekday() 获取周几
# 格式:calendar.weekday(年,月,日)
# 返回值:周几对应的数字
calendar.weekday(2019, 3, 26)

os

os.getcwd() 获取当前的工作目录
os.chdir(路径) 改变当前的工作目录
os.listdir()  获取一个目录中所有子目录和文件的名称列表
os.path.isdir(dir)判读是否是文件夹
os.path.isfile(file)判断是否是文件
os.makedirs(递归路径)
os.curdir    当前目录
os.pardir    父目录
os.sep    当前系统的路径分隔符

time

import time
# 得到时间戳
time.time()

# localtime,得到当前时间的时间元组
# 可以通过点号操作符得到相应的属性元素的内容
t = time.localtime()
print(t.tm_hour)

#asctime() 返回元组的正常字符串化之后的时间格式 
# 格式:time.asctime(时间元组)
# 返回值:字符串 Sun Mar 17 14:12:51 2019
t = time.localtime()
tt = time.asctime(t)

# ctime: 获取字符串化的当前时间
t = time.ctime()

# sleep: 使程序进入睡眠,n秒后继续
time.sleep(3)

# strftime:将时间元组转化为自定义的字符串格式
"""
格式  含义  备注
%a  本地(locale)简化星期名称    
%A  本地完整星期名称    
%b  本地简化月份名称    
%B  本地完整月份名称    
%c  本地相应的日期和时间表示    
%d  一个月中的第几天(01 - 31)   
%H  一天中的第几个小时(24 小时制,00 - 23)   
%I  一天中的第几个小时(12 小时制,01 - 12)   
%j  一年中的第几天(001 - 366)  
%m  月份(01 - 12) 
%M  分钟数(00 - 59)    
%p  本地 am 或者 pm 的相应符    注1
%S  秒(01 - 61)  注2
%U  一年中的星期数(00 - 53 星期天是一个星期的开始)第一个星期天之前的所有天数都放在第 0 周   注3
%w  一个星期中的第几天(0 - 6,0 是星期天) 注3
%W  和 %U 基本相同,不同的是 %W 以星期一为一个星期的开始  
%x  本地相应日期  
%X  本地相应时间  
%y  去掉世纪的年份(00 - 99)    
%Y  完整的年份  
"""
t = time.localtime()
ft = time.strftime("%Y年%m月%d日 %H:%M" , t)

# strptime:将时间的字符串格式变成时间戳
t = time.strptime(ft,"%Y-%m-%d")

random

import random
# random() 获取0-1之间的随机小数
a = random.random()

# choice() 随机返回序列中的某个值
l = [i for i in range(10)]
rst = random.choice(l)
# shuffle() 随机打乱列表
#  格式:random.shuffle(列表)
random.shuffle(l)

# randint(a,b): 返回一个a到b之间的随机整数,包含a和b
random.randint(0,100)

JSON

json本质是字符串(满足一定条件)

  • python对象转换为json对象
    只有基本数据类型才能转换成JSON格式的字符串。也即:int、float、str、list、dict、tuple
    python ——JSON
    dict ——Object
    list,tuple ——array
    str,unicode ——string
    int,float ——number
    True ——ture
    False ——false
    None ——null
json_str = json.dumps(eg)
  • 将数据以json格式存储在文件中
    json模块中dump函数,这个函数可以传入一个文件指针,直接将字符串dump到文件中。
    因为json在dump的时候,只能存放ascii的字符,因此会将中文进行转义,这时候需要修改ensure_ascii=False
books = [
    {
        'title': '钢铁是怎样练成的',
        'price': 9.8
    },
    {
        'title': '自控力',
        'price': 10.0
    }
]
with open('book.json','w',encoding='utf-8') as fp:
    json.dump(books,fp,ensure_ascii=False)
  • 读取json格式文件
eg = json.loads(json_str)

with open('book.json','r',encoding='utf-8') as fp:
    books = json.load(fp)

CSV

  • 读取CSV文件
    可以通过content[n]来选取列表内容,但是如果某个数据缺失,会导致你读取的数据错误。
import csv

with open('stock.csv','r') as fp:
	#reader是一个迭代器
    reader = csv.reader(fp)
    #获取标题
    titles = next(reader)
    for content in reader:
    	#content是一个列表
        print(content)

读取内容为字典

import csv
with open('stock.csv','r') as fp:
	#不包含标题,是迭代器,content是字典
    reader = csv.DictReader(fp)
    for content in reader:
        print(content['name'])
  • 写入CSV文件
    将元组数据写入文件,需要创建一个writer对象,主要用到两个方法。一个是writerow,这个是写入一行。一个是writerows,这个是写入多行
    newline=’\n’默认为\n,写入会自动换行,替换为空字符串解决
import csv

headers = ['name','age','classroom']
values = [
    ('zhiliao',18,'111'),
    ('wena',20,'222'),
    ('bbc',21,'111')
]
with open('test.csv','w',newline='') as fp:
    writer = csv.writer(fp)
    writer.writerow(headers)
    writer.writerows(values)

把字典数据写入进去

import csv

headers = ['name','age','classroom']
values = [
    {"name":'wenn',"age":20,"classroom":'222'},
    {"name":'abc',"age":30,"classroom":'333'}
]
with open('test.csv','w',newline='') as fp:
    writer = csv.DictWriter(fp,headers)
    writer.writeheader()
    writer.writerow({'name':'zhiliao',"age":18,"classroom":'111'})
    writer.writerows(values)

lambda表达式(匿名函数):

一个表达式,函数体相对简单不是一个代码块,仅仅是一个表达式,可以有参数,有多个参数也可以,用逗号隔开

s = lambda x, y : x * y 
s(1, 3)

# 案例
a = (('a'),('b'))
b = (('c'),('d'))
c = zip(a,b)
print(c.__next__())
print(c.__next__())

d = [{i:j} for i,j in zip(a,b)]
print(d)

e = lambda a,b : [{i:j} for i,j in zip(a,b)]
print(e(a,b))

ret = map(lambda t:{t[0]:t[1]},zip(a,b))
print(list(ret),type(ret))

map

把集合或者列表的元素,每一个元素都按照一定规则进行操作,生成一个新的列表或者集合
map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象

l1 = [i for i in range(10)]
def sum(n):
    return n*10
l2 = map(sum, l1 )
# map类型是一个可迭代的结构,所以可以使用for遍历
for i in l2:
    print(i)

reduce

原意是归并,缩减,把一个可迭代对象最后归并成一个结果
对于作为参数的函数要求: 必须由两个参数,必须有返回结果
reduce([1,2,3,4,5]) == f( f(f(f(1,2),3), 4),5)
reduce 需要导入functools包

from functools import reduce
def Add(x,y):
    return x + y
rst = reduce( Add, [1,2,3,4,5,6] )

filter

过滤函数:对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回,利用给定函数进行判断,返回值一定是个布尔值
调用格式: filter(f, data), f是过滤函数, data是数据

def isEven(a):
    return a % 2 == 0
    
l = [3,4,56,3,3,23455,43]
rst = filter(isEven, l)

# 过滤O,NULL
list_a = [0, 2, 3, 0, 22]
list_b = filter(None, list_a)