python学习笔记4--装饰器、生成器、迭代器、匿名函数、内置方法、数据序列话

一、装饰器

  1、意义:当需要给程序中某些函数新增某项功能时,为了避免直接修改函数源代码和函数调用方式,所以引入装饰器。

  2、定义:装饰器用于装饰其他函数,就是为其他函数提供附加功能。

  3、原则:

    1)不修改被装饰的函数的源代码

    2)不修改被装饰的函数的调用方式

  4、装饰器储备知识:

    1)函数即变量

    2)高阶函数

      a.把函数当做参数传递给另一个函数(在不修改被修饰函数源代码的情况下为该函数添加功能)

      b.返回值中包含函数名(在不修改被修饰的函数的调用方式的情况下为该函数添加功能)

    3)嵌套函数:在函数体内重新声明一个新的函数

  5、装饰器类型

    1)不带参数函数的装饰器

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

# 定义装饰器
def decorator1(func):
    def deco():
        print("Running test1!")
        func()
        print("Complete test1")
    return deco

# 装饰不带参数的函数
@decorator1
def test1():
    print("test 1")

test1()
View Code

    2)带参数的函数的装饰器

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

# 修饰带参数的函数
def decorator2(func):
    def deco(*args,**kwargs):
        print("这是\"%s\"的装饰器" % args)
        func(*args,**kwargs)
    return deco

@decorator2
def test2(name):
    print("test 2,name:", name)

test2("张三")
View Code

    3)带参数的装饰器

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

# 带参数的装饰器
def decorator3(flage):
    def warrper(func):
        def deco(*args,**kwargs):
            if flage == 1:
                print("这个函数的flage是:" , flage)
                func(*args,**kwargs)
            else:
                print("这flage是个什么玩意儿?" , flage)
                func(*args,**kwargs)
        return deco
    return warrper

调用装饰器时传入参数
@decorator3(flage=3)
def test3(name, age):
    print("test 3,name:%s,age:%s" % (name, age))

test3("李四",22)
View Code

   6、关于装饰器的理解

    1)不带参数的装饰器

      装饰器在被装饰函数之前定义的时候,@装饰器名,此语法只是引用了装饰器函数,相当于对被装饰函数的函数名进行了重命名,例如:

def decorator1(func):
    def deco():
        print("Running test1!")
        func()
        print("Complete test1")
    return deco

# @decorator1等价于 test1 = decorator1(test1()),等价于test1 = deco,所以,test1()等价于deco()
@decorator1    
def test1():
    print("test 1")

    2)带参数的装饰器

def decorator3(flage):
    def warrper(func):
        def deco(*args,**kwargs):
            if flage == 1:
                print("这个函数的flage是:" , flage)
                func(*args,**kwargs)
            else:
                print("这flage是个什么玩意儿?" , flage)
                func(*args,**kwargs)
        return deco
    return warrper

# @decorator3(flage=3)此处直接调用了decorator3函数,相当于@warrper
@decorator3(flage=3)
def test3(name, age):
    print("test 3,name:%s,age:%s" % (name, age))

 二、生成器

  1、列表生成式

  python中可以通过列表生成式来快速生成列表,例如生成一个列表如下:

  [1*1,2*2,3*3,......,100*100]

  生成这个列表可以用for循环来依次append,但是代码会比较多,此时就可以使用列表生成式来生成这个列表:

>>> list1 = [x*x for x in range(1,101)]
>>> list1
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801, 10000]

  2、生成器

  上述列表生成式生成的列表都完全生成后保存在内存中,如果该列表数据量特别大的时候,有可能会导致内存打满,而且如果需要遍历该变量或者使用某值时,完全创建列表会白白浪费大量的内存空间。生成器的出现就是为了解决这个问题。

  生成器只有在调用时才会生成相应的数据,生成器只保存当前的元素。

# 创建生成器
>>> g = (x*x for x in range(10))
>>> print(g)
<generator object <genexpr> at 0x1012e0ba0>

# 遍历生成器
>>> for i in g:
...     print(i)
... 
0
1
4
9
16
25
36
49
64
81
>>> 

  3、next()方法和__next__()方法

   next()方法和__next__()方法可以返回生成器的下一个值

>>> g = (x*x for x in range(10))
>>> g.__next__()
0
>>> next(g)
1
>>> g.__next__()
4
>>> next(g)
9
>>>

 

   4、yield语句

  通过yield语句可以使一个函数变成一个生成器,只需要把想输出的值变成yield来输出就可以

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

# 此时的函数就是一个生成器了
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        # print(b)
# 用yield替换print()就变成了生成器
        yield b    
        a,b = b,a+b
        n += 1
    return 'done'

f = fib(10)

for i in f:
    print(i)

 

   5、try语句

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        # print(b)
        yield b
        a,b = b,a+b
        n += 1
    return 'done'

f = fib(10)
while True:
    try:
        x = next(f)
        print(x)
    except StopIteration as error:
        print("超过了生成器最大的限制!",error.value)
        break

  6、使用yield实现协程并发

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import time

def eat(name):
    print("%s 准备抢包子吃了!"% name)
    while True:
        baozi = yield
        print("%s包子被%s吃了!" % (baozi,name))

def pro(name):
    print("%s开始做包子了!!!" % name)
    user1 = eat("张三")
    user2 = eat("李四")
    user1.__next__()
    user2.__next__()
    for i in range(10):
        time.sleep(1)
# send()方法,send()方法会向yield返回值
        user1.send(i)
        user2.send(i)

pro("王五")

 三、迭代器

  1、直接作用于for循环的对象统称为可迭代对象,可以使用isinstance()方法判断是否是可迭代对象Iterable
  2、可以被next()函数调用并不断返回下一个值的对象统称为迭代器Iterator
  3、使用iter()方法可以把可迭代对象变成一个迭代器

四、内置方法

abs():取绝对值
all(Iterable):可迭代对象中所有元素都是真则返回True,反之返回False
any(Iterable):可迭代对象中只要有一个元素为真则返回True,反之返回False
ascii(object):
bin(整数):把一个十进制整数转换为二进制
bool():判断真假
bytearray():将一个byte类型的字符串变成可修改字符串
bytes()
callable(参数):判断参数是否可调用
chr(整数):返回对应整数的unicode对应的字符
ord(字符):返回字符对应的unicode中的数字
compile(codestr,'文件名','模式'):将代码当做字符串编译成一个
dir(object):查看对象的方法
divmod(num1,num2):返回num1除以num2的商和余数
eval():
exec():
filter(func,Iterable):从一组可迭代对象中根据func函数的规则返回结果,func可以用lambda匿名函数
map(func,Iterable):把可迭代对象中所有值传递给func处理
frozenset():把集合变为不可变集合
globals():返回整个程序的所有的变量名和值
hash():
hex(数字):转换为16进制
locals():打印局部变量
max():返回列表中最大值
min():返回列表中最大值
oct(数字):十进制转二进制
power(x,y):x的y次方
repr():通ascii
round(float,num):保存num位浮点数
slice():切片
sorted(dict):排序,默认按key排序
sum(list):列表求和
__import__('str'):使用字符串导入模块

 

五、匿名函数

   lambda表达式:

  lambda arguement1,arguement2,...,arguementn:expression

>>> lambda x:x**5 
<function <lambda> at 0x1013dae18>
>>> a = lambda x:x**5
>>> a(5)
3125
>>> a(3)
243
>>>

 六、json和pickle数据序列化

  1、json介绍

  json用于不同语言之间的数据交互,采用键值对的方式记录数据,使用json时需要先导入json模块

  2、json序列化

  json.dump(数据,文件句柄)

  f.write(json.dumps(数据))

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import json

date = {
    "name":"zhangsan",
    "age":30,
    "JOB":"IT"
}

with open("json.txt","w") as f:
    json.dump(date,f)
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import json

date = {
    "name":"zhangsan",
    "age":30,
    "JOB":"IT"
}

with open("json.txt","w") as f:
    f.write(json.dumps(date))

 

   3、json反序列化

  json.loads(数据)

  json.load(文件句柄)

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import json

with open("json.txt","r") as f:
    date = f.read()
    date = json.loads(date)

print(type(date))
print(date)
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import json

with open("json.txt","r") as f:
    date = json.load(f)

print(type(date))
print(date)

 

   序列化的时候只dump一次,也只load一次。

 

posted @ 2016-08-15 18:40  没有手艺的手艺人  阅读(158)  评论(0编辑  收藏  举报