Python_高级特性

一、生成器

生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。能够节省内存使用。

colors = ['black', 'white']
sizes = ['s', 'm', 'l']
for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):
    print tshirt

使用生成器函数yield的等差数列

def aritprog_gen(begin, step, end=None):
    result = type(begin + step)(begin)
    forever = end is None
    index = 0
    while forever or result < end:
        yield result
        index += 1
        result = begin + step * index

二、枚举:Enumerate

enumerate在字典上是枚举、列举的意思。对于一个可迭代/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列
利用它可以同时获得索引和值,多用于在for循环中得到计数

list1 = ["这", "是", "一个", "测试"]
for index, item in enumerate(list1):
    print index, item

enumerate还可以接收第二个参数,用于指定索引起始值

for index, item in enumerate(list1, 2):
    print index, item

如果要统计文件的行数,可以这样写:

with open('my.txt', 'r') as m:
    count = len(m.readlines())

这种方法简单,但是可能比较慢,当文件比较大时甚至不能工作;可以利用enumerate()

count = 0
with open('my.txt', 'r') as m:
    for index, line in enumerate(m):
        count += 1

三、具名元组:Namedtuple
用以构建只有少数属性但是没有方法的类,比如数据库条目。用namedtuple构建的类的实例所消耗的内存跟元组是一样的,因为字段名都被存在对应的类里面。
创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串

from collections import namedtuple

Card = namedtuple('Card', ['rank', 'suit'])
City = namedtuple('City', 'name country population coordinates')

tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
print tokyo  # City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
print tokyo.coordinates  # (35.689722, 139.691667)

四、迭代器

getitem

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]

因为 getitem 方法把 [] 操作交给了 self._cards 列表,所以我们的 deck 类自动支持切片(slicing)操作。

deck = FrenchDeck()
print deck[:3]  # [Card(rank='2', suit='spades'), Card(rank='3', suit='spades'), Card(rank='4', suit='spades')]

另外,仅仅实现了 getitem 方法,这一摞牌就变成可迭代的了

for card in deck:
    print card

于是,in 运算符可以用在我们的 FrenchDeck 类上,因为它是可迭代的

print Card('Q', 'hearts') in deck  # True

同时这个类还可以用于标准库中诸如random.choice、reversed 和 sorted 这些函数

iter

import re, repr

RE_WORD = re.compile('\w+')

这个类可以迭代,因为实现了 iter 方法。
根据可迭代协议,iter 方法实例化并返回一个迭代器。

class Sentence:
    def __init__(self, text):
        self.text = text
        self.words = RE_WORD.findall(text)  # re.findall 函数返回一个字符串列表,里面的元素是正则表达式的全部非重叠匹配

    def __repr__(self):
        return 'Sentence(%s)' % repr(self.text)  # .repr 这个实用函数用于生成大型数据结构的简略字符串表示形式
        # 默认情况下,repr 函数生成的字符串最多有 30 个字符

    # def __iter__(self):
    #     for word in self.words:
    #         yield word
    #     return  # 这个 return 语句不是必要的;这个函数可以直接“落空”,自动返 回。
    #     # 不管有没有 return 语句,生成器函数都不会抛出 StopIteration 异常,而是在生成完全部值之后会直接退出

    def __iter__(self):
        return (match.group() for match in RE_WORD.finditer(self.text))
        # 这里不是生成器函数了 (没有 yield),而是使用生成器表达式构建生成器,然后将其返回。

五、装饰器:Decorate
以函数名作为参数传递给装饰器,同时执行装饰器内部函数。

def clock2(func):
    def clocked(*args, **kwargs):
        result = func(*args, **kwargs)
        name = func.__name__
        arg_lst = []
        if args:
            arg_lst.append(', '.join(repr(arg) for arg in args))
        if kwargs:
            pairs = ['%s=%r' % (k, w) for k, w in sorted(kwargs.items())]
            arg_lst.append(', '.join(pairs))
        arg_str = ', '.join(arg_lst)

        return 'The function %s has args:%s'%(name,arg_str),result
    return clocked

@clock2
def snooze(name):
    return 'welcome to my home, %s'%name

print snooze('regan')  # ("The function snooze has args:'regan'", 'welcome to my home, regan')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值