导航

python学习笔记(4)

Posted on 2018-03-06 14:41  stumn  阅读(142)  评论(0)    收藏  举报

1.装饰器

定义:本质是函数,(装饰其他的函数)就是为其他函数添加附加功能;

原则:1.不能修改被装饰的函数的源代码;

      2.不能修改被装饰函数的调用方式。

实现装饰器的知识储备:1.函数即变量;2.高阶函数;3.嵌套函数。

    高阶函数 + 嵌套函数 = 装饰器

 1 import time
 2 
 3 def timer(func):    #装饰器
 4     def deco(*args, **kwargs):
 5         start_time = time.time()
 6         func(*args, **kwargs)
 7         end_time = time.time()
 8         print('the dunc time is %s'%(end_time - start_time))
 9     return deco
10 
11 @timer      #test1=timer(test1)    test1=deco
12 def test1():
13     time.sleep(1)
14     print("in the test1!")
15 
16 @timer     #test2=timer(test2)
17 def test2(value1, value2):
18     time.sleep(1)
19     print("in the test2:",value1,value2)
20 
21 test1()
22 test2(1,2)

如果被调用的函数有不同的运行选项的话:

 1 import time
 2 
 3 user, passwd = 'mm', '123'
 4 
 5 def auth(auth_type):
 6     print("auth func:", auth_type)
 7     def out_wrapper(func):
 8         def wrapper(*args, **kwargs):
 9             username = input("Username:").strip()
10             password = input("password:").strip()
11             if auth_type == 'local':
12                 if user == username and passwd == password:
13                     print("\033[32;1mUser has passed authentication\033[0m")
14                     res = func(*args, **kwargs) # from home
15                     print('-------after authentication')
16                     return res
17                 else:
18                     print("\033[31;1mInvalid username or password!\033[0m")
19             else:
20                 print("hahahaha......")
21         return wrapper
22     return out_wrapper
23 
24 def index():
25     print("Welcome to index page")
26 
27 @auth(auth_type='local') #本地认证
28 def home():
29     print("Welcome to home page")
30     return 'from home'
31 
32 @auth(auth_type='ldap') #ldap认证
33 def bbs():
34     print("Welcome to bbs page")
35 
36 index()
37 print(home())
38 bbs(

2.匿名函数

mil = lambda x:x*3

不能使用太复杂的语句

3.高阶函数

1.把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

2.返回值中包含函数名(不修改函数的调用方式)

4.生成器

只有在调用时才会生成相应的数据,只记录当前位置,只有一个__next__()方法。

生成器:

c = (i**2 for i in range(10))
print(c.__next__())  0    
print(c.__next__())  1
print(c.__next__())  4

但是,通常使用循环进行打印:

c = (i**2 for i in range(10))
for i in c:
    print(i)

带yield的generator function:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a+b
        n = n+1

fib_gen = fib(10)
print(fib_gen.__next__())  1
print(fib_gen.__next__())  1
print(fib_gen.__next__())  2

其中 a, b = b, a+b 相当于:

t = (b, a+b)
a = t[0]
b = t[1]

yield保持当前中断的值并返回。同时,这个函数就是一个迭代器。

把函数改成generator后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代。

生成器的并行效果:

import time

def consumer(name):
    print('[%s] ready to eat baozi!'%name)
    while True:
        baozi = yield
        print('baozi[%s] was coming, but eaten by [%s]'%(baozi, name))def producer():
    c = consumer('A')
    c2 = consumer('B')
    c.__next__()
    c2.__next__()
    print('I am ready to make baozi!')
    for i in range(10):
        time.sleep(1)
        print("2 baozi were made!")
        c.send(i)   #send调用yield,同时给yield传值
        c2.send(i)

producer()

5.迭代器

直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:

from collections import Iterable
isinstance([], Iterable)  true

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

*可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否是Iterator对象:

from collections import Iterator
isinstance([], Iterator)  false

使用iter()函数将字典, 列表等转换成迭代器:

from collections import Iterator
isinstance(iter([]), Iterator)  true

小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象;

Python的for循环本质上就是通过不断调用next()函数实现的。

6.内置函数

 https://docs.python.org/3/library/functions.html?highlight=built#ascii 

7. json & pickle数据序列化

文件只能存储字符串或者二进制;

1.json,用于字符串 和 python数据类型间进行转换,不同语言之间进行数据交互

import json    #json只能处理简单的数据类型,比如列表,字符串,字典等

# data = {"name": "Jack", "age": 32}

# with open('j_file.text', 'w')as f:
#     f.write(json.dumps(data))  #json序列化
#     json.dump(data, f)

# with open('j_file.text', 'r')as f:
#     data = json.loads(f.read())  #json的反序列化
#     data = json.load(f)
# print(data)

2.pickle,用于python特有的类型 和 python的数据类型间进行转换

 import pickle    #pickle可以处理python中的一切数据类型

# data = {"name": "Jack", "age": 32}

# with open('j_file.text', 'w')as f:
#     f.write(pickle.dumps(data))  #pickle序列化
#     pickle.dump(data, f)
with open('j_file.text', 'r')as f: data = json.loads(f.read()) #pickle的反序列化
    data = json.load(f) print(data)

附:只dump&load一次

8.软件目录结构规范

木有整理完-^-