码迷,mamicode.com
首页 > 编程语言 > 详细

Python学习week4

时间:2018-09-27 16:57:17      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:传值   一个   iterable   os.path   script   并且   原则   ase   exit   

装饰器:本质是函数,用来装饰其他的函数,为其它函数添加附加功能。

原则:不能改变被装饰函数的源代码和调用方式。

1、函数即‘变量’,定义一个函数相当于把函数体赋值给函数名,匿名函数相当于只有函数体没有函数名

 

def func1():
    print(‘in the function‘)
func2=func1     #和普通的整数赋值一样:a=2 b=a print(b)
func2()

 

2、高阶函数

3、嵌套函数

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

 


 

高阶函数:

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

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

 

技术分享图片
import time
def bar():
    time.sleep(2)
    print(in the bar)
def timer(func):
    start_time=time.time()
    func()
    stop_time=time.time()
    print(the time of running is %s%(stop_time-start_time))
timer(bar)
输出:
in the bar
the time of running is 2.0002079010009766
函数执行计时器

 

技术分享图片
import time
def bar():
    time.sleep(2)
    print(in the bar)
def test(func):
    print(func)     #如果参数是函数,则此处打印的是函数在内存中的位置信息
    func()
    return func
test(bar)       #将函数名作为实参传递给调用函数
#test(bar())     #错误用法,将函数返回值传递给调用函数,不符合高阶函数定义
输出:
<function bar at 0x000001717B027F28>
in the bar
调用函数返回被调用函数名

 

嵌套函数:在一个函数的函数体内定义另一个函数,不是调用,是def定义

技术分享图片
def test():
    print(in the test)
    def inner():        #内部函数,相当于局部变量,只能在test()内部调用
        print(in the inner)
    inner()
test()
输出:
in the test
in the inner
嵌套函数

 

装饰器:

技术分享图片
import time
def timer(func):        #嵌套函数
    def decorator(*args):
        start_time=time.time()
        func(*args)
        stop_time=time.time()
        print(the running time of this function is %s%(stop_time-start_time))
    return decorator        #返回函数名,不能带有括号
@timer      #相当于test=timer(test),timer(test)返回decorator()函数。
def test1():
    time.sleep(2)
    print(in the test1)
@timer
def test2(name,age):
    print(in the test2:, name, age)
test1()
test2(刚田武,22)
输出:
in the test1
the running time of this function is 2.000319242477417
in the test2: 刚田武 22
the running time of this function is 0.0
为函数增加计时功能

 

技术分享图片
username,password=zhhy,123
def auth(auth_type):
    print(auth type:,auth_type)
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            print(wrapper args:,*args,**kwargs)
            if auth_type == local:
                user_name = input(please input your name:).strip()
                pass_word = input(please input your password:).strip()
                if username == user_name and password == pass_word:
                    print(\033[32;1mUser pass authentication\033[0m )
                    result = func(*args, **kwargs)
                    print(after authentication)
                    return result
                else:
                    exit(\033[32;1mInvalid username or password\033[0m )
            elif auth_type==ldap:
                print(using ldap)
        return wrapper
    return outer_wrapper
def index():
    print(welcome to index page)
@auth(auth_type=local)
def home():
    print(welcome to home page)
    return from home
@auth(auth_type=ldap)
def bbs():
    print(welcome to bbs page)
home()
View Code

 


 

列表生成式:生成列表的简便方法。

print([i*2 for i in range(10)])
输出:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

 i*2可以换成func()。

生成器:generator=(i*2 for i in range(10))

1、数据较多并且有规律时,可以减少内存占用,要调用的数据才会产生;

2、不支持切片操作;

3、只有__next__()方法;

4、只保存当前调用数据。

技术分享图片
generator=(i*2 for i in range(10))
print(generator.__next__())
print(generator.__next__())
输出:
0
2
生成器

 

斐波那契数列:

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

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

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

 

改为生成器:yield b

def fib():
    a,b=0,1
    while True:
        yield b
        a,b=b,a+b
f=fib()
print(f.__next__())

 含有yield的函数称为生成器,生成器的return语句和函数的不同,其return的值赋给异常StopIteration,用try可以捕获异常,避免程序出错。

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator;

函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行;

for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIterationvalue中。

def fib(max):
    n,a,b=0,0,1
    while n<max:
        yield b
        a,b=b,a+b
        n+=1
    return ‘---------done---------‘
f=fib(5)
while True:
    try:
        # x=next(f)
        # print(‘f:‘,x)
        print(f.__next__())
    except StopIteration as e:
        print(‘生成器返回值:‘,e.value)
        break
输出:
1
1
2
3
5
生成器返回值: ---------done---------

 yield可以在单线程环境中进行类似并行计算,称为协程。

 

import time
def consumer(name):     #不断吃包子
    print(‘[%s]来吃包子,‘%name)
    while True:
        baozi=yield     #baozi的值由send()方法传来
        print(‘[%s]包子被[%s]吃了‘%(baozi,name))
def producer(name):
    a=consumer(‘刚田武‘)       #consumer是生成器,不会执行
    b=consumer(‘胖虎‘)
    a.__next__()        #调用next()后才会执行,consumer运行到baozi=yield处退出此生成器,等待send()方法传值。
    b.__next__()
    print(‘[%s]开始做包子‘%name)
    for i in range(5):
        time.sleep(2)
        print("做了2个包子")
        a.send(‘白菜馅‘)       #send()传值给baozi后,a运行print(‘[%s]包子被[%s]吃了‘%(baozi,name)),然后循环运行到baozi=yield跳出
        b.send(‘番茄馅‘)
producer("朱二娃")
输出:
[刚田武]来吃包子,
[胖虎]来吃包子,
[朱二娃]开始做包子
做了2个包子
[白菜馅]包子被[刚田武]吃了
[番茄馅]包子被[胖虎]吃了

 


 

 迭代器:

 可以直接作用于for循环的数据类型有以下几种:一类是集合数据类型,如listtupledictsetstr等;一类是generator,包括生成器和带yield的generator function。

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

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

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

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator,可以通过iter()函数获得一个Iterator对象。[http://www.cnblogs.com/alex3714/articles/5765046.html]

from collections import Iterator
from collections import Iterable
print(isinstance([],Iterator))        #列表不是迭代器对象,返回False
print(isinstance([],Iterable))        #列表是可迭代对象,返回True
print(isinstance(iter([]),Iterator))        #iter()后的列表是可迭代对象,返回True
输出:
False
True
True

 


json序列化和反序列化:可以把内存中的数据存储到硬盘中,便于下次从硬盘中读取数据,相当于把程序暂停。

只能进行简单的数据类型序列化,可以在不同编程语言或者程序之间交互数据。

技术分享图片
import json
info={"name":"刚田武",age:20}
f=open(test.text,w)
print(json.dumps(info))
f.write(json.dumps(info))
序列化json.dumps()
技术分享图片
import json
f=open(test.text,r)
data=json.loads(f.read())
print(data[name])
反序列化json.loads()

 pickle和json类似,优点是可以序列化所有数据类型,包括函数。序列化函数时,反序列化只能得到函数名,没有函数体,需要把函数体复制到反序列化中。可以更改函数体。

技术分享图片
import pickle
def hello(name):
    print(hello,,name)
info={name:刚田武,age:20,func:hello}
f=open(test.text,wb)
f.write(pickle.dumps(info)) #pickle.dump(info,f)效果相同
序列化pickle.dumps()
技术分享图片
import pickle
def hello(name):
    print(hello,,name)
f=open(test.text,rb)
data=pickle.loads(f.read())     #data=pickle.load(f)
data[func](刚田武)
反序列化pickle.loads()

 

软件目录结构规范:层次清晰的目录结构规范有助于提高程序的可读性和可维护性。

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: 项目说明文件。[https://www.cnblogs.com/alex3714/articles/5765046.html]

从atm文件夹下的atm.py文件中调用core文件夹下的main.py的方法:

import os,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))    #找到程序的根目录
sys.path.append(BASE_DIR)       #添加环境变量,BASE_DIR是当前程序的根目录,便于调用其他文件夹下的程序文件。
from core import main
from conf import setting
main.login(刚田武)

其中main.py为:

def login(name):
    print(‘welcome to atm ,‘,name)

 输出为:

welcome to atm , 刚田武

 

Python学习week4

标签:传值   一个   iterable   os.path   script   并且   原则   ase   exit   

原文地址:https://www.cnblogs.com/zhhy236400/p/9670829.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!