函数进阶

函数名的使用

for循环机制

捕获异常

嵌套的升级:闭包

迭代器

 

  在说明函数名的使用时,必须熟记函数的结构:

def func():
  print(123)
print(func())                            #  加括号是对函数的调用
print(func)                              #   不加括号是打印函数的内存地址

函数名的使用:

  1,函数名可以当做值赋给变量

def func():
     print(1)
a=func                        函数名可以当做值赋给变量
a()
func()

  2,函数名可以当做参数去传递

def func():
    print(22)
def func2(msg):
    print(msg)
func2(func)            将函数名func赋给了msg,此时输出的结果是函数func的内存地址
                  ps:如果在传递时func加括号,就是在传递func函数的返回值:None

  3,函数名可以当做返回值被返回

def foo():
    print(2)
def func(msg):
    print(1)
    return msg             (msg = foo,将foo赋值给了msg,返回的是内存地址)     
                           msg如果加括号(),就是在调用foo
print(func(foo))           输出内容是:1,和foo的内存地址

  在这里插入一个比较绕的:接力

def foo():          
    print(1)     
    return "你好啊"  # 将"你好啊"返回给foo,赋给ret
def func():          
    print(2)
    ret = foo()   # 将foo()赋给ret,调用foo
    return ret    # 将ret返回给func,赋给msg
def func2():         
    print(3)
    msg = func()  # 将func()赋值给msg,调用func
    return msg    将msg回退给func2,返回值为:"你好啊"
print(func2())      # 先调用fun2                输出结果为:3,2,1,"你好啊"

4,函数名可以当做元素存放在容器当中

  lst = [foo,func,func2]
  print(lst)

5,查看函数的内存地址,print(函数名)

for i in lst:  (遍历,也称for循环),当有大批量的函数要调用时,就用这个方法

    i( )    调用时要在后面加个括号

闭包:

定义:在嵌套函数内,内部函数使用外部变量(非全局变量)就是闭包

优点:可以保护这个变量不被外界修改,延长变量的生命周期,提高效率,节省开辟空间和销毁空间的时间差

def func():
    name = '小五子'
    print(name)
func()                   定义完函数,用一次就消失了,开辟的空间清空

def func():
    name = '小五子'      (当把变量name放在这个位置时,就是闭包),持久力增强,生命周期延长,常驻在内存里
    def foo():
      print(name)            
    foo()                   
func()

查看闭包的内存地址:(函数名.__closure__)

def func():
    name = '小五子'
    def foo():
        print(name)
    foo()    
func()
          查看闭包:print(foo.__closure__)
          foo的内存地址:(<cell at 0x000001B9F15095E8: str object at 0x000001B9F14DC088>,)

例1:

def func():
    n = 100
    def foo():
        n = 10
        def f1():
            print(n)
        return f1           返回给foo
    return foo               返回给func
func()
print(func())         拿到foo的内存地址  <function func.<locals>.foo at 0x000002647C610BF8>
print(func()())        拿到f1的内存地址  <function func.<locals>.foo.<locals>.f1 at 0x000002647C610C80>
print(func()()())     拿到 n = 10

例2:

def get_url():
    url ='666'
    def get():
        s = 4
        print(url)
        def urls():
print(s)
return urls
return get
msg = get_url()    
msg()()
              msg()调用get函数
              msg()()调用urls函数

迭代器:

  可迭代对象:要遵守迭代协议,只要有__iter__方法的,就是可迭代对象,可以被for循环

  迭代器:要遵守迭代器的协议,有__iter__和__next__方法的就叫迭代器

      创建一个迭代器 == 可迭代对象.__iter__()

    使用迭代器,就是 == 迭代器.__next__()

lst = [1,2,3]                (三个获取的都是1)
l1 = lst.__iter__().__next__()
l2 = lst.__iter__().__next__()
l3 = lst.__iter__().__next__()    print(l1),print(l2),print(l3)都是1

那么换一种方式呢?

lst = [1,2,3]
l1 = lst.__iter__()          从一个可迭代对象转化为迭代器
print(l1.__next__())
print(l1.__next__())
print(l1.__next__())          此时输出的结果为1,2,3,如果继续往下再加__next__(),就会报错

 输出可迭代对象的内存地址

print(str.__iter__('你好'))      <str_iterator object at 0x0000017BF45116D8>
print(list.__iter__([1,2,3]))    <list_iterator object at 0x0000017BF450B3C8>
print(dict.__iter__({'1':2}))    <dict_keyiterator object at 0x0000017BF450C4A8>
print(set.__iter__({1,2,3}))     <set_iterator object at 0x0000017BF45196C0>
print(tuple.__iter__((1,2,3)))      <tuple_iterator object at 0x0000017BF45116D8>
print(range.__iter__(range(1,5)))   <range_iterator object at 0x0000017BF4526D70>

*****for循环的机制

lst = [1,2,3,4,5]
count = 0
l = lst.__iter__()
while count < len(lst):
  print(l.__next__())
  count += 1

  异常捕获:

lst = [1,2,3,4,5,6]
l1 = lst.__iter__()
while True:
    try:
        print(l1.__next__())
    except StopIteration
        break

迭代器的特性:

  惰性机制,是一次性的;而且迭代器不能回退

检测迭代器:(迭代器一定是可迭代对象,可迭代对象不一定是迭代器)

  from collections import Iterable,Iterator

Itrator是否是迭代器

Iterable,是否是可迭代对象

print(isinstance([1,2,3],Iterator))     False  
print(isinstance([1,2,3],Iterable))     True

print(isinstance('123',iterator))       False
print(isinstance('123',iterable))       True

print(isinstance(123,iterable))        False
print(isinstance(123,iterable))        False
posted @ 2019-01-13 14:20  DF-包子  阅读(163)  评论(0编辑  收藏  举报