1、dir(__builtins__)可以查看python的内置函数
要查看某个BIF是干什么的,可以在shell中键入help(方法名),如, help(len),就会得到这个BIF的功能描述.如下:
2、显示列表的内置函数
dir(list)
3、利用whilce实现 for 循环
string = "FishC" it = iter(string) while Treu: try: each = next(it) except Stopiteration: break print(each)
4、元组、集合
元组:你的一个函数要返回两个值,这时就可以用“return (a, b)”这样的形式返回一个元组,因为它是不可更改的数据序列。
列表:大箩筐,什么都可以往里装。
字典:比如同时返回网站标题、网址,就可以用字典。
集合:你采集了一大堆的网址,这时最好用集合,因为它包含的数据不重复(与字典类似,但只包含键,而没有对应的值),相当于给你自动去重了呀!而且比如采集关键词,有人用“return list(set(all_words))”这样的形式,先去重,再返回list。
Json:返回大量的数据。
5、python的换行
6、装饰器、迭代器、生成器:
一个简单的迭代器
l = [1,2,3,4,5,6,7]#建立一个列表l ite = l.__iter__()#__iter__()代表l是一个可迭代的对象 print(ite.__next__(),"使用iterator.__next__()方法输出")#代表ite是一个迭代器 print(next(ite),"使用next(iterator)方法输出")#l两种输出方式均可以 while True: try: print(next(ite))#遍历输出ite剩余的元素 except StopIteration:#对Stop告警的异常处理 break
生成器:
生成器必须是可迭代的,它是非常方便的自定义迭代器。
一个简单的生成器
>>> my_generator = (x*x for x in range(4)) >>> dir(my_generator) ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
发现my_generator中在迭代器中必有的方法'__iter__','__next__',,这说明它是迭代器。
我们把含有yeild语句的函数称作生成器。
装饰器:
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
实质: 是一个函数
参数:是你要装饰的函数名(并非函数调用)
返回:是装饰完的函数名(也非函数调用)
作用:为已经存在的对象添加额外的功能
特点:不需要对对象做任何的代码上的变动
以前你有没有这样一段经历:很久之前你写过一个函数,现在你突然有了个想法就是你想看看,以前那个函数在你数据集上的运行时间是多少,这时候你可以修改之前代码为它加上计时的功能,但是这样的话是不是还要大体读读你之前的这个的代码,稍微搞清楚一点它的逻辑,才敢给它添加新的东西。这样是不是很繁琐,要是你之前写的代码足够乱足够长,再去读它是不是很抓狂...。实际工作中,我们常常会遇到这样的场景,可能你的需求还不只是这么简单。那么有没有一种可以不对源码做任何修改,并且可以很好的实现你所有需求的手段呢?答案当然是有,这就是今天我们要介绍的python装饰器。
我们还是以为函数添加计时功能为例,讲述函数装饰器。
import time def decorator(func): def wrapper(*args, **kwargs): start_time = time.time() func() end_time = time.time() print(end_time - start_time) return wrapper @decorator def func(): time.sleep(0.8) func() # 函数调用 # 输出:0.800644397735595
为什么需要装饰器?
我们假设你的程序实现了say_hello()和say_goodbye()两个函数。
def say_hello(): print "hello!" def say_goodbye(): print "hello!" # bug here if __name__ == '__main__': say_hello() say_goodbye()
但是在实际调用中,我们发现程序出错了,上面的代码打印了两个hello。经过调试你发现是say_goodbye()出错了。老板要求调用每个方法前都要记录进入函数的名称,比如这样:
[DEBUG]: Enter say_hello() Hello! [DEBUG]: Enter say_goodbye() Goodbye!
好,小A是个毕业生,他是这样实现的。
def say_hello(): print "[DEBUG]: enter say_hello()" print "hello!" def say_goodbye(): print "[DEBUG]: enter say_goodbye()" print "hello!" if __name__ == '__main__': say_hello() say_goodbye()
小B工作有一段时间了,他告诉小A可以这样写。
def debug(): import inspect caller_name = inspect.stack()[1][3] print "[DEBUG]: enter {}()".format(caller_name) def say_hello(): debug() print "hello!" def say_goodbye(): debug() print "goodbye!" if __name__ == '__main__': say_hello() say_goodbye()
是不是好一点?那当然,但是每个业务函数里都要调用一下debug()函数,是不是很难受?万一老板说say相关的函数不用debug,do相关的才需要呢?
一个简单的写法
def debug(func): def wrapper(): print "[DEBUG]: enter {}()".format(func.__name__) return func() return wrapper @debug def say_hello(): print "hello!"
这是最简单的装饰器,但是有一个问题,如果被装饰的函数需要传入参数,那么这个装饰器就坏了。
def debug(func): def wrapper(*args, **kwargs): # 指定宇宙无敌参数 print "[DEBUG]: enter {}()".format(func.__name__) print 'Prepare and say...', return func(*args, **kwargs) return wrapper # 返回 @debug def say(something): print "hello {}!".format(something)