神奇的python系列10:函数(三)

1.函数名使用及第一类对象

函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量.

1.函数名的内存地址

def func():
    print(1)

print(func)  #内存地址 <function func at 0x027B34B0>

2.函数名可以赋值给其他变量

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

3.函数名可以当做参数去传递

def func():
    
    return '大姑娘美'

def func2(msg):    # mag = func
    print(msg)   # msg???  func内存地址

func2(func())  # 函数名可以当做参数去传递      注意点 传递函数名的时候如果+()就是在传递这个函数的返回值

4.函数名可以作为函数的返回值

def foo():
    print(2)
    # 当函数没有写return默认返回None
def func(msg):
    print(1)

    return msg
print(func(foo))        # 函数名可以当做返回值被返回

5.函数名可以当做元素存放在一个容器当中

def func1():   
    print("哈哈")
def func2():   
    print("呵呵")
def func3():   
    print("嘿嘿")
def func4():  
     print("哼哼")
lst = [func1, func2, func3]  # 函数名可以当做元素存放在一个容器当中
for i in lst:  
     i()


2.闭包

闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包

def func1():
    name = "你好"
    def func2():
        print(name)
        # 闭包
    func2()
func1()
# 结果: 你好

使用函数名.__closure__来检测,返回cell就是闭包. 返回None就不是闭包

def func():
    name = '宝元'
    def foo():
        print(name)
    foo()
    print(foo.__closure__)  # (<cell at 0x007C1370: str object at 0x007C45C0>,)
func()

print(func.__closure__)  # 返回的结果不是None就是闭包
def outer():   
    name = "你好"   
    # 内部函数   
    def inner():       
        print(name)   
    return inner
fn = outer()   # 访问外部函数, 获取到内部函数的函数地址
fn()    # 访问内部函数 

多层嵌套中的使用:

def func1():   
    def func2():       
        def func3():       
            print("嘿嘿")      
        return func3 
    return func2
func1()()() 

嵌套函数,在嵌套函数内,内部函数使用外部变量(非全局变量) 就是一个闭包 闭包可以多层。

闭包的好处:

1.保护变量不会被外界修改

2.函数内使用到的变量会生命周期延长

3.节省开辟空间和销毁空间的时间


3.迭代器

遵守迭代协议(标准):
  1.遵守迭代器的协议 具有__iter__()方法和__next__()方法
  2.可以被for循环的就是可迭代对象(除去int和bool,str,list,tuple,dict,set,range()这些都是可迭代)

print(dir(str))   # 查看这个类型中有什么功能  可迭代__iter__
#查看是迭代器还是可迭代对象:

from collections import Iterator,Iterable
print(isinstance('查看的内容',Iterable))   # 查看是否是可迭代的
print(isinstance('查看的内容',Iterator))   # 查看是否是迭代器

# 迭代器一定是可迭代的,但是可迭代的不一定是迭代器

如果对象中有__iter__函数,那么我们认为这个对象遵守了可迭代协议.就可以获取到相应的迭代器。

lst = [1,2,3,4,5,6]

l = lst.__iter__()   # 从一个可跌代对象转换成迭代器
print(l.__next__())
print(l.__next__())
print(l.__next__())
print(l.__next__())
print(l.__next__())
print(l.__next__())
print(l.__next__())

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,67,7]
l = lst.__iter__()
while True:
    try:   # 异常捕获
        print(l.__next__())
    except StopIteration:
        break

注意: 迭代器不能反复,只能向下执行

总结:

      Iterable: 可迭代对象. 内部包含__iter__()函数        

      Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().        

迭代器的特点:            

      1. 节省内存.            

      2. 惰性机制            

      3. 不能反复, 只能向下执行.

      4. 一次性的

原文地址:https://www.cnblogs.com/xianyuwangzhe/p/10274746.html