函数名的应用,闭包,迭代器

一.函数名的应用

1.函数名的定义

  函数名的命名规范和变量一样

  函数名其实就是变量名(函数的应用同变量名一样)

2.函数名的应用

(1)函数名可以赋值

#1,函数名可以进行赋值
a = 10       #变量名的赋值
b = a   
print(b)
    
def func()         #函数名的赋值(函数名赋的是内存地址加()是调用函数)
    print("我是一个函数")
a = func  # 把函数名func的内存地址赋值给了a
print(a)  #打印函数的内存地址
a()       #a() 和func()的意义是一样的

(2) 可以作为列表中的元素进行存储.

语法:

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

lst = [func1, func2, func3]
for el in lst:
    el()

(3).可以作为参数传递给函数

语法:
def func():
     pass
def proxy(fn):
     fn()
proxy(func)
def my():
    print("这是my")
def proxy(fn):     #代理模式.  装饰器
    print("处理之前") 
    fn()
    print("处理之后")
proxy(my)    #把函数名作为参数传递给另一个函数
def func1():
    print("我是func1")
def func2():
    print("我是func2")
def func(fn, gn): # 函数名可以作为参数进行传递
    print("我是func")
    fn()
    gn()
    print("哈哈哈")
func(func1, func2)

(4)可以作为函数的返回值

语法:
def func():
    def inner()
        pass
    return inner
func()()
def func():
    print("我是func")
    a = 10  #变量
    def inner()
        print("我是inner")
    return inner
ret = func()
ret()  #  ret() 和  inner()的含义一样
func()()   #先运行func(), 然后在返回值上加上()

二.闭包

1.闭包定义;在内层函数中访问外层函数的局部变量

2.闭包的好处:

  (1).保护你的变量不受外界影响

为什么能保护变量不受影响呢?
    当我们在全局中定义一个变量a=10后,在局部可以用global进行调用修改
当变量a被反复修改后我们就不知道此时变量a的值是多少了,----全局中的变量不安全
    

  (2).可以让变量常驻内存(可以在爬虫中使用)

在爬虫中,每次爬取网站上的东西会很慢,可以让爬下的内容常驻内存,使用时直接打印

3.闭包的写法:

def outer():

  a= 10   #常驻内存, 为了inner执行的时候有值

  inner()

    priint(a)

  return inner

因为inner()调用的时机是不定的,为了inner能够执行a=10要一直在内存中

4.超简易爬虫

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)

5.查看函数是否是闭包

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

三.迭代器

1.使用dir来查看该数据包含了那些方法

  dic()

s = 123
for i in s:
    print(i)
print(dir(str)) #  dir查看xx类型的数据可以执行哪些方法, __iter__  iterable
print(dir(list)) # __iter__
print(dir(int)) # 没有__iter__
所有的带__iter__可以使用for循环的, 可迭代对象

可迭代对象可以使用__iter__()来获取到迭代器
迭代器里面有__next__()

2.迭代器作用:

  用来遍历列表,字符串,元组....等可迭代对象

s = "石可心喜欢赵一宁"
print(it.__next__()) #
print(it.__next__())    #
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#
print(it.__next__())#

3.可迭代对象:Iterable,里面有__iter__()可以获取迭代器,没有__next__()

    迭代器:Iterator,里面有__iter__()可以获取迭代器,有__next__()

 4.for循环的内部机制.

    1. 首先获取到迭代器.
2. 使用while循环获取数据
3. it.__next__()来获取数据
4. 处理异常 try:xxx except StopIteration:
it = xx.__iter__() #获取xx的迭代器
while 1:
try: #尝试执行
data = it.__next__() #获取下一个元素
xxxxxx
except StopIteration: #处理错误
break

5.迭代器特点:

  (1)只能向下走

  (2)惰性机制

  (3)几乎不占内存, 节省内存(用生成器解释)

6.判断数据是否可迭代,是否是迭代器(2种方法)第一种:偏方

 print("__iter__" in dir(it))        (1)  

 print("__next__" in dir(it))      (2)

(1)(2)同时时True,则it是迭代器,(1)是True(2)是False,则it是可迭代对象

可以通过dir来判断数据是否是可迭代的, 以及数据是否是迭代器

第二种:官方方案

isinstance()  判断xx是否是某一类型的某一实例 . 返回值是True和False,

from collections import Iterable  # 可迭代对象
from collections import Iterator # 迭代器

print(isinstance(lst, Iterable)) #判断lst是否是可迭代的的某一实例 
print(isinstance(lst, Iterator))

print(isinstance(it, Iterable))
print(isinstance(it, Iterator))
lst = ["赵四","花生哥, 越来越皮", "天台见"]
it = lst.__iter__()

# it.__next__()
# it.__next__()
# list(参数)把参数进行循环迭代
s = list(it) # 在list中.一定存在for. 一定__next__()
print(s) # ["赵四","花生哥, 越来越皮", "天台见"]

四.其他知识点

1.list(n)  #把数据类型转换成列表的数据类型

内部发生的变化:

首先n必须是可迭代对象,list中有for对n进行迭代取出每个元素,加入列表中

2.sum()  #求和

sum中可以直接接受一个可迭代对象. 他会把这个可迭代对象进行迭代. 把每个元素累

print(sum([3,5,7]))

2.return print(a)#打印不能返回任何结果

3.函数形参中的默认值参数:

  默认值参数的默认值是可变的数据类型,则默认值一直是同一个

4.print有一个end=" " 是不换行的意思

原文地址:https://www.cnblogs.com/Bug66/p/9456344.html