python note 11 函数名的使用、闭包、迭代器

1、函数名就是一个变量

def func():
    print("我是一个小小的函数")
a = func
print(a)
#输出变量存放地址 <function func at 0x00000251AD780048>
func()
#func()等同于a(),输出 我是一个小小的函数

2、函数名是变量名

def func1():
    print("我是1")
def func2():
    print("我是2")
def func3():
    print("我是3")
lst = [func1, func2, func3]
for el in lst:
    el()
#输出 我是1 我是2 我是3

3、函数名可以作为参数传递给函数

def my():
    print("我是my")
def proxy(fn): # 代理模式. 装饰器
    print("在处理之前")
    fn()
    print("在处理之后")
proxy(my) # 把函数名作为参数传递给另一个函数
#输出 在处理之前 我是my 在处理之后

 

def func1():
    print("我是func1")
def func2():
    print("我是func2")
def func(fn, gn): # 函数名可以作为参数进行传递
    print("我是func")
    fn()
    gn()
    print("哈哈哈")
func(func1, func2)

func()()用法

def func():
    print("我是func")
    a = 10 # 变量
    def inner():
        print("我是inner")
    return inner
ret = func()
ret()
func()() # 先运行func()  然后在返回值上加(),等于上一个写法
#输出 我是func 我是inner

4、闭包

#闭包. 在内层函数中访问外层函数的变量

# 闭包的作用:
# 1. 可以保护你的变量不收侵害
# 2. 可以让一个变量常驻内存

如果不闭包全局变量是不安全的

a = 10 # 不安全的
def outer():
    global a
    a = 20
def outer_2():
    global a
    a = 30
outer_2()
outer()
print(a)
#输出 20
#如果交换outer_2()和outer(),那么输出会变为30

闭包变量会常驻内存

def outer():
    a = 10 # 常驻内存,  为了inner执行的时候有值.
    def inner():
        print(a)
    return inner
fn = outer()
fn() # 调用的时机是不定的.
#输出 10

超简易爬虫

from urllib.request import urlopen
def outer():
    # 常驻内存
    s = urlopen("http://www.xiaohua100.cn/index.html").read()
    def getContent(): # 闭包
        return s
    return getContent
print("爬取内容.....")
pa = outer()
ret = pa()
print(ret)

查看是否闭包

def func():
    a = 10
    def inner():
        print(a)
    print(inner.__closure__)
func()
# 如果打印的是None. 不是闭包. 如果不是None, 就是闭包

 

5、迭代器

#  dir查看xx类型的数据可以执行哪些方法 print(dir(str))、print(dir(list))、print(dir(int))

# 所有的带__iter__可以使用for循环的, 可迭代对象。print(dir(int)) 没有__iter__

# 可迭代对象可以使用__iter__()来获取到迭代器
# 迭代器里面有__next__()
# s = "石可心喜欢赵一宁"
# it = s.__iter__() # 获取迭代器
# print(dir(it)) # 迭代器里有__iter__ 还有__next__

迭代器特性

# 1. 只能向前.
# 2. 几乎不占用内存, 节省内存(需要明天生成器)
# 3. for循环
# 4. 惰性机制 (面试题,难度系数比较高)

s = "石可心喜欢赵一宁"
it = s.__iter__() # 获取迭代器
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#

迭代器模拟for循环

lst = ["赵一宁", "石可心", "朱奎峰", "姚明","潘长江"]
for el in lst: # 底层用的是迭代器
    print(el)

 不输出错误

lst = ["赵一宁", "石可心", "朱奎峰", "姚明","潘长江"]
it = lst.__iter__() # 获取迭代器
while 1:
    try:    # 尝试执行
        el = it.__next__()  # 获取下一个元素
        print(el)
    except StopIteration:   # 处理错误,不显示
        break

判断是否为迭代器

偏方

# print("__iter__" in dir(it))
# print("__next__" in dir(it))
# 可以通过dir来判断数据是否是可迭代的, 以及数据是否是迭代器

官方方案

# from collections import Iterable  # 可迭代对象
# from collections import Iterator    # 迭代器
#
# print(isinstance(lst, Iterable))
# print(isinstance(lst, Iterator))
#
# print(isinstance(it, Iterable))
# print(isinstance(it, Iterator))

 

posted @ 2019-04-21 15:09  P-Z-W  阅读(170)  评论(0编辑  收藏  举报