python三大神器

python三大神器

迭代器

1.什么是迭代器(iter)

迭代器是容器;程序中无法直接创建一个迭代器,只能将别的序列转换成迭代器。
特点:打印迭代器无法查看所有的元素、也无法获取元素的个数;获取元素的时候每次只能获取最前面的那个元素而且元素取一个就会少一个

i1 = iter('abc123')
print(i1)  # <str_iterator object at 0x00000203733254B0>
# print(len(i1)) # 报错

i2 = iter([1, 2, 3])
print(i2)  # <list_iterator object at 0x00000197365954B0>

i3 = iter({'a': 10})
print(i3)  # <dict_keyiterator object at 0x00000197365F2BB0>

2.查

迭代器不管以什么样的方式获取到了某个元素,那么这个元素一定会从迭代器中消失

查单个:next(迭代器) - 获取迭代器中最前面的那个元素

遍历

示例:

print(next(i1))  # a
print(next(i1))  # b

i4 = iter('')
# print(next(i4)) # StopIteration

print(list(i1))  # ['c', '1', '2', '3']

i5 = iter({'a': 1, 'b': 2})
print(list(i5))  # ['a', 'b']
# print(next(i5)) # 报错

生成器

1.什么是生成器

生成器也是容器,其他容器是直接保存多个数据,生成器保存的是产生多个数据的算法
生成器获取数据的方式和特点和迭代器一样。

2.创建生成器

调用一个带有yield关键字的函数就可以得到一个生成器对象

示例:

def func1():
    yield
    print('+++')
    print('===')
    return 100


result = func1()
print(result)  # <generator object func1 at 0x0000024C45B74200>

3.控制生成器产生数据的个数和值

一个生成器的数据和个数由创建生成器调用的那个函数的函数体在执行的时候会遇到几次yield以及每次yield后面的值来决定

示例:

def create1():
    yield 100
    yield 200
    yield 300


gen2 = create1()
# print(list(gen2))   # [100, 200, 300]

print(next(gen2))  # 100


# def create2():
#     x = 0
#     while True:
#         yield x
#         x += 1
#
# gen3 = create2()
# while True:
#     print(next(gen3))


# 练习:写一个生成器可以创建某个Python班级的学时的学号,学号的范围师:python0001-python1000
def stu_id():
    str1 = 'python'
    x = 0
    while x <= 1000:
        x += 1
        yield str1 + f'{x:0>4}'


id = stu_id()
for i in range(1, 1001):
    print(next(id))

4.生成器创建数据的原理

每次获取生成器数据的时候,就回去执行创建这个生成器的函数体,但是每次执行都只会执行到yield就停下来

示例:

def func2():
    print('=======')
    yield 100
    print('+++')
    yield 200
    print('!!!!')
    yield 300


gen4 = func2()
print(next(gen4))
print(next(gen4))
print(next(gen4))

装饰器

1.什么是装饰器 - 给已定义号的函数添加功能的工具

装饰器就是一个函数,这个函数既是实参高级函数,又是返回值高阶函数

2.给函数添加功能

示例:

import time
# 练习:给函数添加功能,统计函数执行的时间
def hello():
    # start = time.time()
    print('hello world')
    # end = time.time()
    # print(f'总时间:{end - start}')


hello()


def factorial(n):
    # start = time.time()
    s = 1
    for x in range(1, n + 1):
        s *= x
    print(s)
    # end = time.time()
    # print(end - start)


factorial(10)
# 解决方案2:
def total_time(fn, *args, **kwargs):
    start = time.time()
    fn(*args, **kwargs)
    end = time.time()
    print(end - start)


total_time(hello)
total_time(factorial, 5)


# 解决方案3:
def func1(fn):
    def new_fn(*args,**kwargs):
        start = time.time()
        result = fn(*args,**kwargs)
        end = time.time()
        print(end - start)
        return result
    return new_fn()

无参装饰器

语法:
def 装饰器名(原函数):
    def 添加完功能的新函数(*args,**kwargs):
        调用原函数
        添加新功能
    return 添加完功能的新函数
    
    
    
def 装饰器名(fn):
    def new_fn(*args,**kwargs):
        result = fn(*args,**kwargs)
        新增功能
        return result
    return new_fn



装饰器名 - 根据新增的功能来命名

示例:

def add_tag(f):
    def new_f(*args, **kwargs):
        print('1111')
        result = f(*args, **kwargs)
        return result

    return new_f


@add_tag
def hello():
    print('hello world')


def sum2(num1, num2):
    return num1 + num2


hello()


# 练习2:写一个装饰器在函数调用结束的时候打印'end'
def end_(f):
    def new_f(*args, **kwargs):
        result = f(*args, **kwargs)
        print('end')
        return result

    return new_f


@end_
def hello():
    print('hello,world')


hello()


# 练习3:写一个装饰器将返回值是数字的函数的返回值变成原来返回值的100倍。  3 -> 300;  'abc' -> 'abc'; 1.23  -> 123
def fanbei(f):
    def new_f(*args, **kwargs):
        result = f(*args, **kwargs)
        if type(result) in (int, float):
            return result * 100
        else:
            return result

    return new_f


@fanbei
def adddata(x):
    return x


print(adddata(1))   # 100
print(adddata('1')) # 1

有参装饰器

有参装饰器语法细化:
def 装饰器名称(参数列表):
    def 无参装饰器(f):
        def new_f(*args,**kwargs):
            result = f(*args,**kwargs)
            添加新功能
            return result
        return new_f
    return 无参装饰器


参数列表 - 看实现装饰器新增功能需不需要额外的数据,需要几个  

示例:

# 写一个装饰器将返回值是数字的函数的返回值变成原来返回值的指定倍
def fanbei(n):
    def fanbei1(f):
        def new_f(*args, **kwargs):
            result = f(*args, **kwargs)
            if type(result) in (int, float):
                return result * n
            else:
                return result

        return new_f

    return fanbei1


@fanbei(5)
def adddata(x):
    return x


print(adddata(6))


# 练习:写一个装饰器,用法如下
# 没有装饰器返回值如果是100 @tag(p) -> <p>100</p>
# 没有装饰器返回值如果是'abc' @ tag(a) -><a>abc</a>
def add1(n):
    def add(f):
        def new_f(*args, **kwargs):
            result = f(*args, **kwargs)
            return f'<{n}>{result}</{n}>'

        return new_f

    return add


@add1('p')
def adddata1(x):
    return x


print(adddata1('abc'))
print(adddata1(100))


# 练习3:写一个装饰器(针对返回值是数字的函数),用法如下
# 12 -> @operation('+',100) -> 112
# 12 -> @operation('-',20) -> -8
# 12  -> @operation('*', 3)      -> 36
# 12  -> @operation('/', 3)      -> 4.0
def calculate(x: str, nums: int):
    def calculate1(f):
        def new_f(*args, **kwargs):
            result = f(*args, **kwargs)

            return eval(str(result) + x + str(nums))

        return new_f

    return calculate1


@calculate('*', 10)
def adddata2(n):
    return n


print(adddata2(10))  # 100


@calculate('-', 10)
def adddata3(n):
    return n


print(adddata3(10))  # 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值