首页 > 代码库 > python基础,python第四课

python基础,python第四课

第四课学习的主要内容有生成器,迭代器,pyton装饰器,python开发规范,Json & pickle 序列化与反序列化

生成器

列表生成式

>>> b = [i+1 for i in range(0,10)]
>>> b
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

生成器(Generator)

生成器的一种简单写法,把上面的列表生成式的[],换成()就成了生成器了,python3.0中通过__next__调用

>>> b = (i+1 for i in range(10))  
>>> b
<generator object <genexpr> at 0x0000000003088518>
>>> b.__next__()
1>>> b.__next__()
2
>>> b.__next__()
3
>>> b.__next__()
4
>>> b.__next__()
5
>>> b.__next__()
6
>>> b.__next__()
7
>>> b.__next__()
8
>>> b.__next__()
9
>>> b.__next__()
10
>>> b.__next__()  
Traceback (most recent call last):  #当调用生成器数据超出范围时,解释器会抛出异常,可以通过异常处理来解决
  File "<pyshell#39>", line 1, in <module>
    b.__next__()
StopIteration
>>> b = (i+1 for i in range(10))
>>> while True:
    try:
        a=b.__next__()
        print(a)
    except StopIteration as e:
        print("end")
        break

    
1
2
3
4
5
6
7
8
9
10
end

用一个函数来实现斐波那契数列(Fibonacci),如:1, 1, 2, 3, 5, 8, 13, 21, 34, ...  ,除第一个和第二个数外,任意一个数都等于前两个数相加的和。

 1 >>> def fib(max):
 2     a=0
 3     b=1
 4     n = 0
 5     while n < max:
 6         print(b)
 7         a,b = b,a + b    #该行等于 t = (b,a+b) ,t[0] = b ,t[1]=a+b
 8         n += 1
 9     return "done"
10 
11 >>> f=fib(10)
12 1
13 1
14 2
15 3
16 5
17 8
18 13
19 21
20 34
21 55
22 >>> print(f)
23 done

把上面实现斐波那契数列的函数中的print(b) 改为 yield b 就成了生成器

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

>>> fib(10)
<generator object fib at 0x00000000030AACA8>

上面生成器执行过程与函数过程有所不同,函数执行到return返回,生成器在执行过程中遇到yield 就返回停止执行,当下次再次执行,程序从yield 的位置继续执行

通过yield实现单线程下的并行计算效果

import time
#消费者
def consumer(name):
    print("%s准备好吃包子了"%name)
    while True:
        baozi = yield
        print("%s吃%s个包子."%(name,baozi))
#生产者
def producer(name):
    a = consumer("A")
    b = consumer("B")
    a.__next__()    #初始化
    b.__next__()    #初始化
    print("%s要开始做包子了:"%name)
    for i in range(1,10):   #做包子
        time.sleep(1)
        a.send(i)           #做一个包子发送给a,yield = 1,继续执行,
        b.send(i)           #做一个包子发送给b,并执行

producer("zhangsan")

迭代器

for循环的数据类型:

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

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

  • 可迭代(Iterable):可以直接作用于for循环的对象。
  • 迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象。

可以使用isinstance方法Iterable和Iterator

#判断是否是可迭代对象
>>> from collections import Iterable>>> isinstance([],Iterable) True >>> isinstance({},Iterable) True>>> isinstance((x for i in range(10)),Iterable) True #判断是否是迭代器 >>> from collections import Iterator >>> isinstance([],Iterator) False >>> isinstance({},Iterator) False >>> isinstance((x for i in range(10)),Iterator) True

可迭代对象可以通过iter()变成迭代器

>>> isinstance(iter([1,2,3,4]),Iterator)
True

装饰器

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

原则:

  1. 不能修改被装饰的函数的源代码
  2. 不能修改被装饰的函数的调用方式

实现装饰器需要掌握的知识

  1. 函数即“变量”
  2. 高级函数

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

b:返回值包含函数名(不修改函数的调用方式)

  3.嵌套函数

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

装饰器普通版

import time
#装饰器
def timer(func):    #timer(test1)  func =test1
    def deco():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("func run time is",stop_time - start_time)
    return deco #返回deco 内存地址

@timer          #test1 = timer(test1)
def test1():
    time.sleep(2)
    print("in the test1")
@timer
def test2():
    time.sleep(3)
    print("in the test2")


test1()
test2()

 

装饰器高潮版

user,passwd = "zhangxin","abc123"

def auth(auth_type):
    print(auth_type)
    def wrapper_auther(func):
        def wrapper(*args, **kwargs):
            if auth_type == "local":
                username = input("Please input username:").strip()
                password = input("Please input password:").strip()
                if user == username and passwd == password:
                    print("Login successful")
                    func(*args, **kwargs)
                    return  func
                else:
                    print("Account or password error")
            elif auth_type == "ldap":
                print("不会ldap")
        return wrapper
    return wrapper_auther  #


def index():
    print("Welcome to index")

@auth(auth_type = "local")        #装饰器加参数
def home():
    print("Welcome to home")
    return "from home"

@auth(auth_type = "ldap")
def setting():
    print("Welcome to setting")

index()
print(home())
setting()

json序列化与反序列化

json序列化

 1 import json
 2 
 3 data =http://www.mamicode.com/ {
 4     "name":"zhangsan",
 5     "age": 28,
 6     "city":"beijing"
 7 }
 8 f = open("json file1","w",encoding="utf-8")
 9 #f.write(json.dumps(data))#序列化
10 json.dump(data,f) #json.dump(data,f) ==json.dump(data,f)  
11 f.close()

json反序列化

import json

f = open("json file1","r",encoding="utf-8")
#data = http://www.mamicode.com/json.loads(f.read()) #反序列化
data = http://www.mamicode.com/json.load(f) # json.loads(f.read()) ==   json.load(f)
print(data)
f.close()

python开发目录规范

目录结构

Foo/
|-- bin/
|   |-- foo
|
|-- foo/
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py
|
|-- docs/
|   |-- conf.py
|   |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README

解释:

  1. bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。
  2. foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py
  3. docs/: 存放一些文档。
  4. setup.py: 安装、部署、打包的脚本。
  5. requirements.txt: 存放软件依赖的外部Python包列表。
  6. README: 项目说明文件。

作业

ATM作业需求

  1. 额度 15000或自定义
  2. 实现购物商城,买东西加入 购物车,调用信用卡接口结账
  3. 可以提现,手续费5%
  4. 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息
  5. 支持多账户登录
  6. 支持账户间转账
  7. 记录每月日常消费流水
  8. 提供还款接口
  9. ATM记录操作日志 
  10. 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
  11. 用户认证用装饰器

 

python基础,python第四课