博客信息

Python核心编程(列表推导式、生成器、迭代器、闭包、装饰器)

发布时间:『 2019-07-30 23:02』  博客类别:Python  阅读(702)

列表推导式

 

生成器:

    Python中, 一边循环一边计算的机制, 称为生成器: generator

创建生成器: G = ( x*2 for x in range(5))

可以通过 next(生成器) 函数获得生成器的下一个返回值

没有更多的元素时, 抛出 StopIteration 的异常

生成器也可以使for 循环,因为生成器也是可迭代对象

 

创建生成器的方式:

    1.

        g = (列表推导式)

    2.

        Yield

 

 

列表推导式的代码体现形式

# list1 = [2,4,6,8...10]
list1 = []
#循环操作
for i in range(2,101,2):
    list1.append(i)
print(list1)
#列表推导式
list2 = [x for x in range(2,101,2)]
list3 = [x for x in range(101) if x % 2 == 0 if x != 0 if x >=50]
print(list2)
print(list3)


生成器的使用

 

创建生成器

# 生成器的定义方式  g = (列表推导式)
g = (x for x in range(101) if x % 2 == 0 if x != 0 if x >=50)
print(type(g))
# print(g)
print(next(g))
print(next(g))
print('-'*50)
#使用for循环遍历生成器能生成的所有的数据
for v in g:
    print(v)
print('-'*50)
#超出生成器生成的范围“StopIteration”异常
# print(next(g))
# print(g.__next__())

print("yield关键字....................")

def test():
    for x in range(10):
        #加入yield关键字,函数调用变成生成器
        yield x
        print("----")
        # print(x)
g = test()
# print(type(g))
#生成一个数据
# 输出0,程序在yield关键字停下
print(g.send(None))
# 输出(----,1),程序又在yield关键字停下
print(next(g))
# 输出(----,2),程序又在yield关键字停下
print(g.__next__())
# 输出(----,3),程序又在yield关键字停下
print(g.send(""))


必须清楚yield关键字参与后的方法执行顺序

生成器在线程中的使用

def save_money():
    while True:
        print("存入¥1999")
        yield None
def draw_money():
    while True:
        print("取出Y1999")
        yield None

g_save = save_money()
g_draw = draw_money()

while True:
    # save_money()
    # draw_money()
    g_save.__next__()
    g_draw.__next__()


迭代器的使用

迭代器:

    迭代:

        遍历的一种方式

 

    可迭代性:iterable

        如何判断一个对象是否具备可迭代性?

            1.判断目标对象是否属于Iterable类   instance

            2.for 循环

 

        论证

            测试列表,字符串,元组,字典,生成器是否具备可迭代性,

 

 

    迭代器: Iterator

        能够使用next()函数调用,并不断返回下一个值的对象,称为迭代器

        生成器是否是迭代器?

        列表、元组、字符串、字典是否是迭代器? 不是

     结论:

1、具备可迭代性的不一定是迭代器

2、将具备可迭代性的对象转换为迭代器

iter(具备可迭代性的对象)

from collections.abc import Iterable,Iterator

list1 = [x for x in range(10)]

#测试列表是否具备可迭代性
if isinstance(list1,Iterable):
    for x in list1:
        print(x,end=' ')

print()
#字符串是否具备可迭代性

str1 = 'HelloWorld'
if isinstance(str1,Iterable):
    for ch in str1:
        print(ch,end=" ")

print()
tuple1 = tuple(list1)
#元组是否具备可迭代性
if isinstance(tuple1,Iterable):
    for x in tuple1:
        print(x,end=' ')

print()

#测试字典是否具备可迭代性
dict1 = {'one':1,'two':2,'three':3,'four':4,'five':5}
if isinstance(dict1.values(),Iterable):
    for v in dict1.values():
        print(v,end=" ")

print()
#测试生成器是否具备可迭代性
g = (x for x in range(10))
if isinstance(g,Iterable):
    for x in g:
        print(x,end=' ')

print()
#判断生成器是否为迭代器
if isinstance(g,Iterator):
    print("生成器就是迭代器")
    # next(g)

if isinstance(list1,Iterator):
    print("列表是迭代器")
else:
    print("列表不是迭代器")

list1 = iter(list1)
if isinstance(list1, Iterator):
    print("转换后的列表是迭代器")
else:
    print("列表不是迭代器")

print(next(list1))

all_items = dict1.items()
print(type(all_items))
if isinstance(all_items,Iterable):
    for k,v in all_items:
        print(k,v)

all_items = iter(all_items)
print(type(all_items))
if isinstance(all_items,Iterator):
    print("是迭代器")
else:
    print('No')


闭包的使用

什么是闭包?

        嵌套定义的函数,内部函数使用外部变量,内部函数就称为闭包。

 

    如何定义一个闭包?

        1.函数嵌套定义

        2.内部函数使用外部函数作用域内的变量

        3.外部函数必须有返回值,返回内部函数名

 

    闭包的使用!

        好处:

            将外部函数中,局部变量的生命周期延长,程序周期

 

闭包代码体现形式的区别

# 普通函数定义方式
def test(num1,num2):
    print(num1+num2)
test(10,20)

#外部函数
def func_out(num1):
    #内部函数 闭包
    def func_in(num2):
        return num1 + num2
    return func_in

func_in123 = func_out(10)
print(type(func_in123))
result = func_in123(20)
print(result)

result1 = func_in123(100)
print(result1)

result2 = func_in123(30)
print(result2)

func_in = func_out(20)
# result3 = func_in123(30)  40
result3 = func_in(30)
print(result3)


闭包的应用

"""
用法:

    求原点到指定点的距离
    sqrt((x-x1)^2  + (y-y1)^2)

    1.函数
    2.闭包

"""

import math
#求两个点之间的距离
def get_dis(x,y,x1,y1):
    return math.sqrt((x-x1)**2 + ((y-y1)**2))

print(get_dis(0,0,3,4))
print(get_dis(0,0,30,40))


def get_dis_out(x,y):
    def get_dis_in(x1,y1):
        return math.sqrt((x - x1) ** 2 + ((y - y1) ** 2))
    return get_dis_in

#使用变量get_dis_in 存储get_dis_out(0,0) 的返回值(返回值为一个函数名)
get_dis_in = get_dis_out(0,0)
#
print(get_dis_in(3,4))
print(get_dis_in(30,40))


结论:在某些业务开发的场景中可能需要利用到闭包,比如说游戏开发中的两点之间的距离计算,利用闭包可以简化代码的书写;

装饰器的使用

个人认为装饰器是闭包的一种体现形式。

我们用一个业务需求来说明装饰器在开发中的使用场景。

 

需求:

在已有的两个方法中添加日志功能

1. 记录事件  2.记录时间  3.写入日志文件

 

功能v1.0写法

import time
def write_log(file_name,func_name):
    # 记录当前时间,记录访问方法,写入日志文件
    try:
        file = open(file_name, 'a', encoding='utf-8')
        time_str = time.ctime()
        content = time_str + '\t' + func_name + '\n'
        file.write(content)
    except Exception as e:
        print(e)
    finally:
        file.close()

def func1():
    write_log('log.txt','func1')
    print("功能1")
def func2():
    # 记录当前时间,记录访问方法,写入日志文件
    write_log('log.txt', 'func2')
    print("功能2")

func1()
func2()


功能v2.0写法(不改动原有代码)

"""
开发中的开闭原则:
    开放:
        添加功能开放

    关闭:
        修改源码

"""
import time
def write_log(file_name,func_name):
    # 记录当前时间,记录访问方法,写入日志文件
    try:
        file = open(file_name, 'a', encoding='utf-8')
        time_str = time.ctime()
        func_name = func_name
        content = time_str + '\t' + func_name + '\n'
        file.write(content)
    except Exception as e:
        print(e)
    finally:
        file.close()

def func1():
    print("功能1")
def func2():
    print("功能2")

#使用闭包完成功能的添加
def func_out(func,file_name):
    def func_in():
        #新增功能(写入日志文件)
        write_log(file_name,func.__name__)
        #func是传进来的一个函数,调用函数
        func()
    return func_in

func1 = func_out(func1,'log.txt')
func1()
func2 = func_out(func2,'log.txt')
func2()


功能v3.0写法

import time
def write_log(file_name,func_name):
    # 记录当前时间,记录访问方法,写入日志文件
    try:
        file = open(file_name, 'a', encoding='utf-8')
        time_str = time.ctime()
        func_name = func_name
        content = time_str + '\t' + func_name + '\n'
        file.write(content)
    except Exception as e:
        print(e)
    finally:
        file.close()

#使用闭包完成功能的添加
def func_out(func):
    def func_in():
        #新增功能(写入日志文件)
        write_log('log.txt',func.__name__)
        #func是传进来的一个函数,调用函数
        func()
    return func_in

#func1 = func_out(func1)
@func_out
def func1():
    print("功能1")

#func2 = func_out(func2)
@func_out
def func2():
    print("功能2")

# func1 = func_out(func1,'log.txt')
# func1()
# func2 = func_out(func2,'log.txt')
# func2()
func1()
func2()


上面这种方式,就是用装饰器替代了闭包的使用,从而简化了代码的书写,并且同时也没有改动原有的业务代码;



over...... 


关键字:     Python       核心编程  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有