Home >  > Python笔记

Python笔记

0

1、dir(__builtins__)可以查看python的内置函数

Snap52

要查看某个BIF是干什么的,可以在shell中键入help(方法名),如, help(len),就会得到这个BIF的功能描述.如下:
Snap53

2、显示列表的内置函数

dir(list)
Snap7

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、装饰器、迭代器、生成器:
一个简单的迭代器

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)
本文暂无标签

发表评论

*

*