python全栈开发 第十一天 随笔 函数名 闭包及迭代器

python全栈开发 课程 随笔  Day 11

今日主要内容:

1,函数名的运用

2.闭包

3.迭代器

一.函数名的运用

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

 函数名其实就是变量名

(1)函数名的内存地址

例:

def func():
    print("alex")
print(func)
 #<function func at 0x0000000002033E18>

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

例:

def func():
 print("呵呵")
print(func)
a = func              # 把函数当成一个变量赋值给另一个变量
a() 
 # 函数调用 func()
函数名可以作为参数传递给函数
def my():
    print("我是my")
def proxy(fn):        # 代理模式. 装饰器
    print("在处理之前")
    fn()
    print("在处理之后")
proxy(my)    #把函数名作为参数传递给另一个函数

a = 10   b =a(赋值操作)    print(b)

(3)函数名可以作为列表的元素进行存储.

例:

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

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

例:

 def func(): pass def proxy(fn): fn() proxy(func) 

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

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

例:

 def func(): def inner(): pass return inner func()() 

def func():
    print("我是func")
    a = 10 # 变量
    def inner():
        print("我是inner")
    return inner
# ret = func()    #(最后一行的转化过程源头)
# ret()              #(最后一行的转化过程源头)
func()() # 先运行func()  然后在返回值上加()
def func_1():
     print("这里是函数1")
     def func_2():
         print("这里是函数2")
     print("这里是函数1")
     return func_2
fn = func_1() # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上面函数2
fn() # 执行上面返回的函数        

二.闭包

闭包:内层函数, 对外层函数(非全局)的局部变量的引用

写法:

def outer():
                a = 10
                def inner():
                    print(a)
                return inner

例:

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

闭包的作用;

(1) 保护你的变量不受侵害.

例:

a = 10            # 不安全的
def outer():
    global a       #如果没有global 就无法引用外部变量,保证内部变量不外泄.不被侵犯
    a = 20
def outer_2():
    global a
    a = 30
outer_2()
outer()
print(a)

(2)可以让一个变量常住内存.供后面的程序使用.

例:

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

简易爬虫实例(邱彦涛(涛哥)珍藏校花美女大全)

例:

# 超简易爬虫
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)
# (过段时间)
ret = pa()
print(ret)
# (又过一段时间调用)
ret = pa()
print(ret)
# (又又过一段时间调用)
ret = pa()
print(ret)
# ...............(此处省去 N + 1 次)

(3)如何查看是否闭包.

方法: 我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是闭包. 返回None就不是闭包.

例:

def func1():
     name = "alex"
     def func2():
         print(name)               # 闭包
     func2()
     print(func2.__closure__) 
func1()

# (<cell at 0x10c2e20a8: str object at
0x10c3fc650>,)
 
def func():
    a = 10
    def inner():
        print(a)
    print(inner.__closure__) # 如果打印的是None. 不是闭包. 如果不是None, 就是闭包
func()


#(<cell at 0x00000000026465B8: int object at 0x000000005286B560>,)

三.迭代器.

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

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

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

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

 数据必须是可迭代的

例:

# 对的
s = "abc"
for c in s:
     print(c)



# 错的
for i in 123:
     print(i)
    结果:
 Traceback (most recent call last):
     File "/Users/sylar/PycharmProjects/oldboy/iterator.py", line 8, in
 <module>
         for i in 123:
    TypeError: 'int' object is not iterable

迭代数据类型和迭代器

(1)可迭代对象可以使用__iter__()来获取到迭代器

(2)迭代器里面有__next__()

例:

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循环的, 可迭代对象



结果:
1
2
3
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

查看一个对象是否是可迭代对象的方法:

(偏方)

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

(官方方法)

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

迭代器的特点:

1. 只能向前.

2. 几乎不占用内存, 节省内存(需要明天生成器)

3. for循环

4. 惰性机制 (面试题,难度系数比较高)

例:

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


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循环(使用while循环+迭代器来模拟for循环(必须要掌握))

for循环的内部机制.

  1. 首先获取到迭代器.

  2. 使用while循环获取数据

  3. it.__next__()来获取数据

  4. 处理异常 try:xxx          except StopIteration:

写法:

it = lst.__iter__() # 获取迭代器
while 1:
    try:    # 尝试执行
        el = it.__next__()  # 获取下一个元素
        print(el)
    except StopIteration:   # 处理错误
        break


#####  (   重    点   )   #####

    1.proxy : 代理        2.stop interation : 停止迭代    3. enfine ; 定义

猜你喜欢

转载自www.cnblogs.com/qq1426794755/p/9457572.html
今日推荐