主要内容:
1. 函数名的使用以及第?类对象
函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量。
(1) 函数名的内存地址
def func():
    print("呵呵")
print(func)            #<function func at 0x000001EBCE5D6048>
(2)函数名可以赋值给其他变量
def func():
    print("呵呵")
print(func)
a = func      # 把函数当成?个变量赋值给另?个变量
a()           # 函数调?用 func()       #呵呵
(3)函数名可以当做容器类的元素
def func1():
    print("呵呵")
def func2():
    print("呵呵")
def func3():
    print("呵呵")
def func4():
    print("呵呵")
lst = [func1, func2, func3]
for i in lst:
    i()
(4)函数名可以当做函数的参数
def func():
    print("吃了了么")
def func2(fn):
    print("我是func2")
    fn()    # 执行传递过来的fn
    print("我是func2")
func2(func)     # 把函数func当成参数传递给func2的参数fn.
(5)函数名可以作为函数的返回值
def func_1():
    print("这里是函数1")
    def func_2():
            print("这里是函数2")
    print("这里是函数1")
    return func_2
fn = func_1()   # 执?函数1.  函数1返回的是函数2, 这时fn指向的就是上面函数2
fn()    # 执?上面返回的函数
(6) 一个设计模式
def panpan():
    print("我是潘潘. 我喜欢毒丈夫 ")
def xiaoping():
    print("我是小萍萍. 我喜欢毒丈夫 ")
def daguanren():
    print("大官人喜欢xxxx")
def wangpo(nv, nan): # 核心业务逻辑
    nv()
    nan()
wangpo(xiaohua, daguanren)             # 王婆代理了大官人和潘潘
(7)函数名既然是变量,变量名是任意的,在多次的赋值和调用过程中后续可能不知道初始的变量名,可以通过.__name__ 来得到初始的变量名
def chi():
    print("我是吃")
a = chi
haha = a
hehe = haha
bilibili= hehe
bilibili()
print(bilibili.__name__) # 函数名
(8)函数的注释
def play(wanjv1, wanjv2, wanjv3):
    ‘‘‘
        这是一个关于玩儿的函数
        :param wanjv1: 玩具1
        :param wanjv2: 玩具2
        :param wanjv3: 玩具3
        :return: 开心
    ‘‘‘
    print("我要玩儿荡秋千")
    return "开心"
# play("独木桥", "独轮车", "独眼龙")
print(play.__doc__) #  document   以文档的形式查看注释
print(str.join.__doc__)   #查看join里面是什么东西
#结果:
# 这是一个关于玩儿的函数
# :param
# wanjv1: 玩具1
# :param
# wanjv2: 玩具2
# :param
# wanjv3: 玩具3
# :return: 开心
# 
# S.join(iterable) -> str
# Return a  string which is the  concatenation of the strings in the iterable.The separator between elements is S.
2. 闭包
闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包
def func1():
    name = "alex"
    def func2():
        print(name)     # 闭包
    func2()
func1()       # alex
我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是闭包,返回None就不是闭包
def func1():
    name = "alex"
    def func2():
        print(name)     # 闭包
    func2()
    print(func2.__closure__)     #(<cell at 0x000001AF73627588: str object at 0x000001AF736B7378>,)
func1()       # alex
在函数外边调用内部函数
def outer():
    name = "alex"
    # 内部函数
    def inner():
        print(name)
    return inner
fn = outer()         # 访问外部函数, 获取到内部函数的函数地址
fn()                 # 访问内部函数
如果多层嵌套,只需要一层一层的往外层返回
def func1():
    def func2():
        def func3():
            print("嘿嘿")
        return func3
    return func2
func1()()()
闭包的好处:
3. 迭代器
str, list, tuple, dict, set. 那为什么我们可以称他们为可迭代对象呢, 因为他们都遵循了可迭代协议.
# 对的
s = "abc"
for c in s:
    print(c)
    
#  错的
for i in 123:
 print(i)
结果:
Traceback (most recent call last):
 File "E:/Python_workspace/day 011/011整理.py", line 111, in <module>
  for i in 123:
TypeError: ‘int‘ object is not iterable
‘int‘ object is not iterable‘ 即如果整数类型对象是不可迭代的,iterable表示可迭代的,表示可迭代协议,我们可以通过dir函数来查看类中定义好的
所有包含了__iter__的东西都可以使用for循环. 都可以进行迭代
s = "我的哈哈哈" print(dir(s)) # 可以打印对象中的?方法和函数 print(dir(str)) # 也可以打印类中声明的?方法和函数
s = "alex" print(dir(s)) # 在字符串中发现了__iter__. 没有__next__ a = 123 print(dir(a)) # 在int中没有__iter__ 没有__next__ lst = [1, 2, 3,] print(dir(lst)) # 在list中也有__iter__
(1)调用了__iter__(), 访问__iter__()可以得到迭代器
lst = [1, 2, 3, 4, 5, 6]
it = lst.__iter__()  # iterator 迭代器
while 1:
    try:
        print(it.__next__())
    except StopIteration:
        print("结束了")
        break
for el in lst:
    print(el)
else:
    print("结束了")
(2) 迭代器给所有的数据类型提供了一种统一的遍历的方式(可迭代协议), Iterable, __iter__()
lst = [1, 2, 3, 4, 5]
print("__iter__" in dir(lst))    #True
print("__next__" in dir(lst))    #False
lst = [1, 2, 3, 4, 5]
it = lst.__iter__()
print("__iter__" in dir(it)) #  迭代器里面是有__iter__的.  迭代器一定是可迭代的     #True
print("__next__" in dir(it))                                                     #True
#
for el in it: # 迭代器可以使用for循环
    print(el)
Iterable: 可迭代对象. 内部包含__iter__()函数
Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().
from collections import Iterable # 可迭代的 from collections import Iterator # 迭代器 # lst = ["周润发","麻花藤","刘伟"] print(isinstance(lst, Iterable)) # instance 实例, 对象 #True print(isinstance(lst, Iterator)) # instance 实例, 对象 #False # it = lst.__iter__() print(isinstance(it, Iterable)) # instance 实例, 对象 #True print(isinstance(it, Iterator)) # instance 实例, 对象 #True
迭代器的特点:
原文:https://www.cnblogs.com/avit/p/10209814.html