python第十天-核心篇2

迭代器

迭代:访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

1.可迭代对象

可以直接作用于for循环的数据类型,一类是集合数据类型,如list,tuple,dict,set,str等,一类是generator,包括生成器和带yield的generator function,这些对象统称为可迭代对象iterable

2.判断是否可迭代

用ininstance()判断一个对象是否是iterable对象。

from collections.abc import Iterator #3.8版本collection改为collection.abc
isinstance([1,2,3],Iterator)

iter()函数

把list、dict、str等iterable变成iterator可以使用iter()函数

isinstance(iter([]),Iterator)

闭包

#定义一个函数
def test(number):
    #在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么僵这个函数以及用到的一些变量称之为闭包
    def test_in(number_in):
        print("in test_in 函数,number_in is %d"%number_in)
        return number+number_in
    #其实这里返回的就是闭包的结果
    return test_in

闭包的应用

# def line_conf(a,b):
    # def line(x):
        # print(a*x+b)
    # return line
# line1 = line_conf(1,1)
# line1(2)
# line1(3)
    
def createNum(a,b,x):
    print(a*x+b)
a=1
b=1
x=0
creatNum(a,b,x)
#之前要看a*x+b,都得改

vim里面所有行添加注释 :%s/^/#/g  如果几行添加:1-14s/^/#/g

装饰器

程序开发经常会用到的功能,用好如虎添翼,面试必问。写代码遵循开放封闭原则,已经实现的功能代码不允许被修改,但可以被扩展。

@函数名是python的一种语法糖 有特殊功能

def w1(func):
    print("---正在装饰---")
    def inner():
        print("---正在验证权限---")
        func()
    return inner
#只要python解释器执行到了这个代码,那么久会自动的进行装饰,而不是等到调用的时候再装饰
@w1
def f1():
    print("---f1---")
def func():
    print("----func--1---")
    def func_in():
        print("----func_in--1---")
        ret = functionName()#保存返回来的haha
        print("---func_in---2---")
        return ret#把haha返回到17行处的调用
    
    print("---func---2---")
    return func_in

@func
def test():
    print("---test---")
    return "haha"

ret = test()
print("test return value is %s"%ret)

装饰器执行的时间

def w1(func):
    print("---正在装饰---")
    def inner():
        print("---正在验证权限---")
        func()
    return inner
#只要python解释器执行到了这个代码就会自动进行装饰,而不是等到调用再装
@w1
def f1():
    print("---f1---")
#调用F1之前已经进行装饰了
f1()

使用装饰器对无参数的函数进行装饰

def func(functionName):
    print("---func---1---")
    def func_in():
        print("---func_in---1---")
        functionName()
        print("---func_in---2---")
    print("---func---2---")
    return func_in
@func
def test():
    print("---test---")
test()

使用装饰器对有参数的函数进行装饰

def func(functionName):
    print("---func---1---")
    def func_in(a,b):#如果a,b没有定义,会导致16行的调用失败
        print("---func_in---1---")
        functionName(a,b)#如果没有把a,b当做实参传递,会导致调用12行函数失败
        print("---func_in---2---")
    print("---func---2---")
    return func_in
@func
def test(a,b):
    print("---test-a=%d,b=%d---"%(a,b))
test(11,22)

使用装饰器对不定长参数的函数进行装饰

def func(functionName):
    print("---func---1---")
    def func_in(*args,**kwargs):#如果a,b没有定义,会导致16行的调用失败
        print("---func_in---1---")
        functionName(*args,**kwargs)#如果没有把a,b当做实参传递,会导致调用12行函数失败
        print("---func_in---2---")
    print("---func---2---")
    return func_in
@func
def test(a,b,c):
    print("---test-a=%d,b=%d,c=%d---"%(a,b,c))
@func
def test2(a,b,c,d):
    print("---test-a=%d,b=%d,c=%d,d=%d---"%(a,b,c,d))
test2(11,22,33,44)

使用装饰器对带有返回值的函数进行装饰

def func(functionName):
    print("---func---1---")
    def func_in():
        print("---func_in---1---")
        ret = functionName()#保存 返回来的haha
        print("---func_in---2---")
        return ret#把haha返回到17行处的调用
    print("---func---2---")
    return func_in
@func
def test():
    print("---test---")
    return "haha"

ret = test()
print("test return value is %s"%ret)

通用装饰器

def func(functionName):
    def func_in(*args,**kwargs):
        print("---记录日志---")
        ret = functionName(*args,**kwargs)
        return ret
    return func_in
@func
def test():
    print("---test---")
    return "haha"
@func
def test2():
    print("---test2---")
@func
def test3(a):
    print("---test3-a=%d--"%a)
ret = test()
print("test return value is %s"%ret)

a = test2()
print("test return value is %s"%a)

test3(11)

带有参数的装饰器

def func_arg(arg):
    def func(functionName):
        def func_in():
            print("---记录日志-arg=%s--"%arg)
            if arg=="heihei":
                functionName()
                functionName()
            else:
                functionName()
        return func_in
    return func
#1. 先执行func_arg("heihei")函数,这个函数return的结果是func这个函数的引用
#2.@func
#3. 使用@func对test进行装饰
@func_arg("heihei")
def test():
    print("---test---")
test()
#带有参数的装饰器,能够起到在运行时,有不同的功能
@func_arg("haha")
def test2():
    print("---test2---")
test2()

作用域

命名空间  小二所在的班级

LEGB规则

locals -->enclosing function -->globals -->builtins

locals 当前所在命名空间(如函数、模块) ,函数的参数也属于命名空间内的变量

enclosing 外部嵌套函数的命名空间(闭包中常见)

def fun1():
    a = 10
    def fun2():
        #a位于外部嵌套函数的命名空间
        print(a)

globals,全局变量,函数定义所在模块的命名空间

a = 1
def fun():
    #需要通过global指令来声明全局变量
    global a
    #修改全局变量,而不是创建一个新的local变量
    a = 2

builtins,内建模块的命名空间

python在启动时会自动为我们载入很多内建的函数、类,比如dict,list,type,print都位于__builtin__模块中,可以用dir(__builtin__)查看

python动态添加属性以及方法

class Person(object):
    def __init__(self,newName,newAge):
        self.name = newName
        self.age = newAge
laowang = Person("老王",1000)
print(laowang.name)
print(laowang.age)
laowang.addr = "北京..."#对象添加属性
print(laowang.addr)

laozhao = Person("老赵",18)
#print(laozhao.addr)

Person.num = 100#类添加属性
print(laowang.num)
print(laozhao.num)

添加方法

import types
class Person(object):
    def __init__(self,newName,newAge):
        self.name = newName
        self.age = newAge
    def eat(self):
        print("---%s正在吃---"%self.name)
def run(self):
    print("----%s正在泡---"%self.name)
        
p1 = Person("p1",10)
p1.eat()
#p1.run = run
#p1.run()#虽然p1对象中run属性已经指向10行的函数,但这句代码还不正确
        #因为run属性指向的函数是后来添加的,并没有把p1当做第一个参数,导致第10行函数调用的时候,出现缺少参数的问题
p1.run = types.MethodType(run,p1)#函数名,实体对象,def run(self)把参数p1传进去run函数
                                 #p1.run作为右边的返回值

p1.run()

添加静态方法

class Person(object):
    def __init__(self,newName,newAge):
        self.name = newName
        self.age = newAge
def test():
    print("---static method---")
Person.test = test
Person.test()

添加类方法

class Person(object):
    def __init__(self,newName,newAge):
        self.name = newName
        self.age = newAge
def printNum(cls):
    print("---class method---")
Person.printNum = printNum
Person.printNum()

__slots__的作用

为了达到限制的目的,python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

class Person(object):
    __slots__=("name","age")
P = Person()
P.name = "老王"
P.age = 20
P.score = 100

__slots__定义的属性仅对当前类实例起作用,对继承的子类不起作用

生成器

在python中,一边循环一边计算的机制,称为生成器generator

生成器的第一种方式

a = [x*2 for x in range(10)]#列表生成式
a = [x*2 for x in range(1000000)]#不想直接生成,保留计算方式,每用一个生成一个
b = (x*2 for x in range(10))#把列表生成式的【】换成()
b
next(b)#next()函数获得生成器的下一个返回值

第二种方式

def creatNum():
    print("----start----")
    a,b = 0,1
    for i in range(5):
        print("---1----")
        yield b
        print("---2---")
        a,b = b,a+b
        print("---3---")
    print("---stop---")
a = creatNum()#creatNum()不会调函数生成,而是返回对象,需要找变量保存,生成器对象
for num in a:
    print(num)

send

def test():
    i = 0
    while i < 5:
        temp = yield i 
        print(temp)
        i+=1
t = test()
t.__next__()
t.send("haha")#和next不同点,给yield i整个表达式一个结果,temp接收下次send发过来的值
t.__next__()

强调

上来就写t.send("haha"),要先调用t.__next__()或者先写t.send(None)

生成器完成多任务 

多任务:协程、进程、线程  协程最快

def test1():
    while True:
        print("---1---")
        yield None
def test2():
    while True:
        print("---2---")
        yield None

t1 = test1()
t2 = test2()
while True:
    t1.__next__()
    t2.__next__()

 

posted @ 2018-08-02 09:31  慢慢慢时光  阅读(107)  评论(0编辑  收藏  举报