7. 高级内容

乙醇 创建于 3 个月 之前

最后更新时间 2018-12-12

本文内容基本上翻译自http://cheat.sh/python/:learn)

非原创, 非原创, 非原创!!!

感谢原文社区作者

####################################################
# 7. 高级内容
####################################################

# 生成器
# 生成器会动态生成一些数据,而不是在使用数据前创建数据然后把这些数据储存起来

# 下面的方法(非生成器)会将所有的值翻倍,并存在double_arr变量里
# 如果iterable很大的话,double_arr将是巨大的
def double_numbers(iterable):
    double_arr = []
    for i in iterable:
        double_arr.append(i + i)
    return double_arr


# 运行下面的代码意味着我们首先会将所有的值都加倍然后返回回来
# 最后再检查返回值是否符合特定条件
for value in double_numbers(range(1000000)):  # `test_non_generator`
    print value
    if value > 5:
        break


# We could instead use a generator to "generate" the doubled value as the item
# is being requested
# 我们可以使用生成器来动态加倍必要的值

def double_numbers_generator(iterable):
    for i in iterable:
        yield i + i


# 使用生成器运行之前同样的代码
# 现在我们可以根据运行时逻辑一个接一个的进行加倍
# 一旦value > 5,代码就会break
# 这样我们就不需要把所有的值都加倍一遍了(运行速度会快很多)
for value in double_numbers_generator(xrange(1000000)):  # `test_generator`
    print value
    if value > 5:
        break

# BTW: 你注意到`range` 用在了 `test_non_generator` 而`xrange` 用在 `test_generator`里了嘛?
# 就像`double_numbers_generator` 是  `double_numbers`的生成器版本一样
# `xrange` 是`range`的生成器版本
# `range` 会返回包含1000000个值的列表
# `xrange` 会在我们遍历的时候动态依次创建1000000个值

# 你也可以像使用列表表达式一样使用生成器表达式
values = (-x for x in [1, 2, 3, 4, 5])
for x in values:
    print(x)  # 打印出-1 -2 -3 -4 -5

# 你也可以直接把生成器转换成列表
values = (-x for x in [1, 2, 3, 4, 5])
gen_to_list = list(values)
print(gen_to_list)  # => [-1, -2, -3, -4, -5]


# 装饰器
# 装饰器是高阶函数,可以接受函数作为参数并返回函数
# 简单的例子 – add_apples装饰器会将 'Apple' 元素插入 into
# 到目标函数(被装饰的函数)get_fruits返回的列表里
def add_apples(func):
    def get_fruits():
        fruits = func()
        fruits.append('Apple')
        return fruits
    return get_fruits

@add_apples
def get_fruits():
    return ['Banana', 'Mango', 'Orange']

# 打印出的结果里是包含'Apple'元素的
# Banana, Mango, Orange, Apple
print ', '.join(get_fruits())

# 下面的例子里beg 装饰了 say
# Beg会调用say. 如果 say_please 是 True 那么 beg 会修改say的返回值
# message
from functools import wraps


def beg(target_function):
    @wraps(target_function)
    def wrapper(*args, **kwargs):
        msg, say_please = target_function(*args, **kwargs)
        if say_please:
            return "{} {}".format(msg, "Please! I am poor :(")
        return msg

    return wrapper


@beg
def say(say_please=False):
    msg = "Can you buy me a beer?"
    return msg, say_please


print say()  # Can you buy me a beer?
print say(say_please=True)  # Can you buy me a beer? Please! I am poor :(

上一篇: 6. 模块

我要留言

暂无评论