函数

*args:接收溢出位置参数;		  将位置参数存成一个元组的形式
**kwargs:接收溢出的关键字参数;  将关键字函数存成一个字典的形式

一、装饰器

故名思议就是装饰函数用的

二、函数对象:函数可被当做数据传输

  • 函数可以当做传递给另一个函数
  • 一个函数的返回值也可以是一个函数

三、名称空间与作用域

名称空间分为三种

内置名称空间:Python解释器启动则生效
全局名称空间:执行Python文件生效
全局名称空间:调用函数时临时生效,调用结束的时候失效。

  • 加在顺序:先内置函数,在全局,最后有可能产生句部
  • 查找名字的顺序:先局部,在全局,最后内置

作用分两种

全局作用域:全局存活,全局有效
句部作用域:临时存活,句部有效

四、装饰器

闭包函数:定义在函数内部的函数,特点是:包含对外部作用域而不是全局作用域名字的引用,就称之为闭包函数。

x = 1
def outter():
    x = 2
    def inner():
        print(x)
    return inner
f=outter() 
#这里相当于将inner():函数以变量的形式传递给outter()这个函数所以print()打印的是outter中的x = 2

为什么要用装饰器:开放封闭原则,对扩展是开放的,对修改是封闭的

什么事是装饰器:

  • 用来装饰它人,装饰器本身可以是任意可调用对象,被装饰对象也可以是任意可调用对象。
  • 遵循的原则:

1、不修改被装饰对象的源代码
2、不修改被装饰对象的调用方式

  • 目标:在循环原则1和2的前提,被装饰器对象添加上新功能
    用闭包实现装饰器
import time
def index():
	time.sleep(3)
	print("welcome index")
def timmer(func):
	#func = index #最原始的index函数的内存地址
	def inner():
		start_time=time.time()
		index()
		stop_time=time.time()
		print("run time is :[%s]"%(stop_time-start_time))
	return inner
index=timmer(index)
index()
#我们将index函数产地给timmer函数,通过return将inner函数的内容传递给timmer第一层下,这是func为index函数,然后执行。

例:这就是一个装饰器

import time
def timmer(func):
	#func=index #最原始的index函数的内存地址
	def inner():
		start_time =time.time()
		func()
		stop_time = time.time()
		print("run time is :[%s]"%(stop_time - start_time))
	return inner
@timmer #index=timmer(index)
def index():
	time.sleep(3)
	print("welcome to index page")
index()

无参装饰器

import time
from functools import wraps   #这里就是将index的内置属性全都给inner

def timmer(func):
    @wraps(func)
    def inner(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)    #这里是返回源index的返回值
        stop_time=time.time()
        print('run time is :[%s]' %(stop_time-start_time))
        return res                  #这里就是返后index的返回值
    return inner
@timmer
def index():
    '''
    index function
    :return:
    '''
    time.sleep(3)
    print('welcome to index page')
    return 123

@timmer #home=timmer(home) #home=inner
def home(name):
    time.sleep(2)
    print('welcome %s to home page' %name)
    return 456

# res=index() # res=inner()
# print(res)
#
# res=home('egon') #inner('egon')
# print(res)
# print(index.__doc__)
print(help(index))

有参装饰器


import time
current_status={'user':None,'login_status':False}
def auth(egine='file'):
    # egine='file'
    def wrapper(func):
        def inner(*args,**kwargs):
            if current_status['user'] and current_status['login_status']:
                res = func(*args, **kwargs)
                return res

            if egine == 'file':
                u='egon'
                p='123'
            elif egine == 'mysql':
                print('mysql auth')
                u = 'egon'
                p = '123'
            elif egine == 'ldap':
                print('ldap auth')
            else:
                pass
            name = input('username>>:').strip()
            pwd = input('password>>:').strip()
            if name == u and pwd == p:
                print('login successfull')
                current_status['user'] = name
                current_status['login_status'] = True
                res = func(*args, **kwargs)
                return res
        return inner
    return wrapper
@auth(egine='ldap') #@wrapper #index=wrapper(index) #index=inner
def index():
    time.sleep(3)
    print('welcome to index page')
    return 123
index() #inner()

五、迭代器

1、什么是迭代器:迭代器是一个重复过程,每次重复都是基于上一次的结果来的
2、为什么要用迭代器:

对于序列类型:字符串、列表、元组,可以使用基于索引的迭代取值方式;对于没有索引的方式如:字典、集合、文件,这种方式不再适合,于是我们必须超出一种不能依赖于索引的方式;
3、可迭代的对象:只要对象内置有__iter__方法,obj.iter
可迭代对象:字符串、列表、元组、集合、字典、文件。
4、迭代器对象:对象即内置有__iter__方法,有内置有__next__
可迭代对象:文件

注意可迭代对象不一定是迭代器对象,而迭代器对象一定是可迭代对象。迭代器对象自身也有__iter__方法,但是迭代器对象在__iter__就是自己本身。

dic={"a":1,"b":2}
iter_dic = dic.__iter__()
iter_dic.__next__
#通过__iter__()既可以把可迭代对象,转换成得迭代器。

dic={"a":1,"b":2}
iter_dic = dic.__iter__()
iter_dic.__next__
print(iter_dic.__next__())
print(iter_dic.__next__())   
#print(next(iter_dic))
#也可以用next方法来取值;但是超出取值范围,报错。
#处理方法异常处理
dic={"a":1,"b":2}
iter_dic = dic.__iter__()
while True:
	try:
		print(next(iter_dic))
	except StopIteration:
		break

for循环就是依赖这种机制,所以for循环不依赖索引。for循环是调用__iter__()方法来实现。 把它变成迭代器对象。

总结:

迭代器的优缺点:

  • 优点:

提供了一种统一的迭代取值方法,该方法不在依赖于索引;
更节省内存;

  • 缺点:

不可逆的,一次性,无法获取指定位置的值;
无法统计长度;

扩展:

form cllections import iterable,iterator
#可以通过这两种方法判断是不是可迭代对象。iterable可迭代去对象,iterator迭代器

六、生成器

定义:只要函数内部出现yield关键字,那么在调用该函数,将不再会立即执行函数整体代码,会得到一个结果,该结果就是生成器对象。
生成器本质就是迭代器(iter

def func():
    print("==========>1")
    yield 1
    print("==========>2")
    yield 2
    print("==========>3")
    yield 3
g = func()
next(g)
next(g)
next(g)
G:\python3\pythonw3.exe H:/Python项目/草稿/迭代器.py
==========>1
==========>2
==========>3
#注意,如果超出生成器本身个数,会报错。

yield的功能:

  • 为我们提供一个种自定义的迭代器的方式
  • 对比return,可以返回多个值,挂起函数的执行状态

用迭代器模拟range函数

def my_range(start,stop,step=1):  #开始,结束,步长
    while start < stop:
        yield start
        start += step
g=my_range(1,5)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
G:\python3\pythonw3.exe H:/Python项目/草稿/迭代器.py
1
2
3
4
#这里需要注意,当迭代数等于5时候,报错。这也是根据range函数特性。
def eater(name):
    print("%s 开动了"%name)
    while True:
        food = yield          #第一次就是为了初始化停到yield位置
        print("%s 开始吃了 %s"%(name,food))

g = eater("tom")
print(g.send(None))
g.send("骨头")
G:\python3\pythonw3.exe H:/Python项目/草稿/迭代器.py
tom 开动了
None
tom 开始吃了 骨头

#这里需要注意一下,g.end(None)第一次一定要传一个None。才能传递其他值
#send()有两个功能,其中一个就是想next()一样,另一个传值并返回给food.

七、面向过程编程

面向过程编程绝对不是用函数编程那么简单。

面向过程的编程思想:核心是过程二字,过程即解决问题的步骤,即先干了什么,基于该思想去编写程序就好比在设计一条流水线。是一种机械式的编程思想。
优点:将复杂的问题流程化,进而简单化;
缺点:可扩展性差;

#grep -rl 'root' /etc
import os
def init(func):
    def inner(*args,**kwargs):
        g=func(*args,**kwargs)
        next(g)
        return g
    return inner

def search(filepath,target): #找到一个文件路径就往下个阶段传一次
    g = os.walk(filepath)
    for dirname, _, files in g:
        for file in files:
            abs_file_path = r'%s\%s' % (dirname, file)
            target.send(abs_file_path)

@init
def opener(target):
    while True:
        abs_file_path=yield
        with open(abs_file_path,'rb') as f:
            target.send((f,abs_file_path))

@init
def cat(target):
    while True:
        f,abs_file_path=yield
        for line in f:
            res=target.send((line,abs_file_path))
            if res:
                break


@init
def grep(pattern,target):
    tag=False
    pattern = pattern.encode('utf-8')
    while True:
        line,abs_file_path=yield tag
        tag=False
        if pattern in line:
            target.send(abs_file_path)
            tag=True


@init
def printer():
    while True:
        abs_file_path=yield
        print(abs_file_path)




search(r'C:\Users\Administrator\PycharmProjects\19期\day4\a',opener(cat(grep('你好',printer()))))

八、三元表达式

针对简单的if判断

判断成功的结果在左边,失败的在右边。判断在中间

name = input(">>: ")
"tom is boy" if name == "tom" else: "is not tom"

九、列表解析与生成器表达式

l = ["egg%s" %i for i in range(10)]
print(l)
G:\python3\pythonw3.exe H:/Python项目/草稿/day3.py
['egg0', 'egg1', 'egg2', 'egg3', 'egg4', 'egg5', 'egg6', 'egg7', 'egg8', 'egg9']
#列表解析就是针对for循环说的
l = ["egg%s" %i for i in range(10) if i > 4]
#这里就是先处理for循环后边的事,然后在赋值给前边的egg
#那么它的完整语法是这样的
for i in ...:
	if ...:
#从if后边还能加
#for i in ...:
#	if ...:
#如果用()就是生成器可以用next去取值

十、序列化

什么是序列化

把对象(变量)从内存中编程可存储或传输的过程就称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

为什么要序列化

1、保持持久化状态

当计算机断电或者重启之前将当前内存中的所有数据保存下来,一边下次程序执行能给从文件中读取载入数据。例如虚拟机快照。

2、跨平台数据交换

打破平台和语言差异带来的限制,实现了跨平台数据交互。

json和pickle

json表示的对象就是标准的javascript语言的对象,JSON和Python内置的数据类型对应如下:
json格式
过程

内存中的结构化的数据---------->格式json------------>字符串----------------->保存到文件或者基于网络传输


import json
 
dic={'name':'alvin','age':23,'sex':'male'}
print(type(dic))#<class 'dict'>
 
j=json.dumps(dic)
print(type(j))#<class 'str'>
 
 
f=open('序列化对象','w')
f.write(j)  #-------------------等价于json.dump(dic,f)
f.close()
#-----------------------------反序列化<br>
import json
f=open('序列化对象')
data=json.loads(f.read())#  等价于data=json.load(f)
#注意
import json
#dct="{'1':111}"#json 不认单引号
#dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}

dct='{"1":"111"}'
print(json.loads(dct))

#conclusion:
#无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads 注意点

pickle

过程

内存中的结构化的数据----------------->格式pickle------------------->bytes类型-------------->保存到文件或者基于网络传输

import pickle
 
dic={'name':'alvin','age':23,'sex':'male'}
 
print(type(dic))#<class 'dict'>
 
j=pickle.dumps(dic)
print(type(j))#<class 'bytes'>
 
 
f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j)  #-------------------等价于pickle.dump(dic,f)
 
f.close()
#-------------------------反序列化
import pickle
f=open('序列化对象_pickle','rb')
 
data=pickle.loads(f.read())#  等价于data=pickle.load(f)
 
 
print(data['age'])

#需要注意:pickle只能用于Python
posted @ 2017-10-13 23:44  zz小公子  阅读(153)  评论(0)    收藏  举报