函数名的应用

1 ,函数名就是函数的内存地址。
def func():
    print(666)
print(func) #<function func at 0x000001E82CF4C1E0>

 

 2, 函数名可以作为变量。
a = 2
b = a
c = b
print(c)  #2


def func1():
    print(666)
f1 = func1
f2 = f1
f2() #666

 

 

3,函数名可以作为函数的参数。
def func():
    print('in func')

def func1():
    func()
    print('in func1')

def func2(x):
    x()  # func1()
    print('in func2')

func2(func1)
""" in func in func1 in func2 """

 

4.函数名可以当做函数的返回值。

def wraaper():
    def inner():
        print('inner   ')
    return inner
ret = wraaper()  # inner
ret() # inner()
#inner   
def func2():
    print('in func2')

def func3(x):  # x = func2
    print('in func3')
    return x  # func2

f1 = func3(func2)  # func2
f1()
"""
in func3
in func2
"""

 

5.函数名可以作为容器类类型的元素。

a = 6
b = 4
c = 5
l1 = [a,b,c]
print(l1) #[6, 4, 5]

 

def func1():
    print('in func1')

def func2():
    print('in func2')

def func3():
    print('in func3')

def func4():
    print('in func4')
l1 = [func1,func2,func3,func4]
for i in l1:
    i()
"""
in func1
in func2
in func3
in func4
"""
向上面的函数名这种,第一类对象。

第一对象(first—class object) 指
1.可在运行期创建
2.可用作函数参数或者返回值
3.可存入变量的实体
*不明白? 那就记着一句话,就当普通变量用

 

 

 闭包

 

内层函数对外层函数的变量(非全局变量)的引用,并且将函数名返回 这样就形成了闭包。
def wraaper():
    name = 'alex'
    def inner():
        print(name)
    print(inner.__closure__) 

    inner()
    return inner
wraaper()
"""
(<cell at 0x000001D3FEA60738: str object at 0x000001D3FE607880>,)
alex
"""

name = 'alex'
def wraaper():
    def inner():
        print(name)
    print(inner.__closure__)  # None
    inner()
    return inner
wraaper()
"""
None
alex
"""
非全局变量的引用

 

name = 'alex'
def wraaper(n):
    n = 'alex'  #此行是wraaper的name传给了n,相当于内部有个 n=‘alex’
    def inner():
        print(n)
    print(inner.__closure__)  # cell at 0x000002AD93BF76D8:
    inner()
    return inner
wraaper(name)
"""
(<cell at 0x0000027EC2BC0738: str object at 0x0000027EC2ADDAB0>,)
alex
"""

 

__closure__此非判断函数是否闭包,按定义来判断准确。(必须返回函数名才是闭包,此方法不包括返回,所以不是判断条件。)
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
如果这个函数内部形成了闭包,
那么他就不会随着函数的结束而消失。
from urllib.request import urlopen

def index():
    url = "http://www.xiaohua100.cn/index.html"
    def get():
        return urlopen(url).read()
    return get

xiaohua = index()  # get
content = xiaohua()  # get()
print(content.decode('utf-8'))
爬虫

 有了闭包的,那么这个get()函数不会随着函数结束而结束 ,就不会重复生成占用内存,这样就可以节省内存,无线使用。

 迭代器
可迭代对象
for i in 'abc':
    print(i)
"""
a
b
c
"""
for i in 123:
    print(i)  # 'int' object is not iterable
# 对象内部含有__iter__方法就是可迭代对象.
# 可迭代对象满足可迭代协议。
可迭代对象:str list dict,tuple,set,range()
s1 = 'strs'
print(dir(s1))
#['__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', 'isascii', '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']
判断一个对象是否是可迭代对象:
第一个方法
s1 = 'strs'
dic = {'name':'alex'}
print('__iter__' in dir(s1))  #True
print('__iter__' in dir(dic)) #True
第二种方法
from collections import Iterable  #
from collections import Iterator

print(isinstance('alex',Iterable))  # True  可迭代对象成立否
print(isinstance('alex',Iterator))  # False    迭代器成立否

print(isinstance('alex',str))  # True  判断类型
迭代器
对象内部含有__iter__方法且含有__next__方法就是迭代器.
f = open('register', encoding='utf-8')
print('__iter__' in dir(f))   #True
print('__next__' in dir(f))     #True
print('__iter__' in dir(dict))  #True
print('__next__' in dir(dict))  #False
可迭代对象vs迭代器
可迭代对象不能取值,迭代器是可以取值的
可迭代对象 --->(转化成)迭代器
lis = [1, 2, 3]  # 可迭代对象
# ite1 = lis.__iter__()  # 迭代器  <list_iterator object at 0x0000027A183BFFD0>  通过这样转换成迭代器
ite1 = iter(lis)  # 迭代器  <list_iterator object at 0x0000027A183BFFD0>
print(ite1)   # <list_iterator object at 0x0000027A183BFFD0>
迭代器如何取值?  next一次,取一个值
print(ite1.__next__())
print(ite1.__next__())
print(ite1.__next__())
print(ite1.__next__()),超出取值范围就报错。

__iter__   iter()   他们都是一个,只不过是包装成了内置函数。

__next__    next()        他们都是一个,只不过是包装成了内置函数。

特点:

1, 可迭代对象不能取值,迭代器是可以取值的。
2, 迭代器非常节省内存。每次只在内存中只占一个
3,迭代器每次只会取一个值。
4,,迭代器单向的,一条路走到头。

什么时候使用:数据量非常大,且只为了取值。
s1 = 'kfdsjl'
# for i in s1:
#     print(i)

 

while 循环模拟for循环机制
1,将可迭代对象转化成迭代器。
2,调用__next__方法取值。
3,利用异常处理停止报错。
iter1 = s1.__iter__()
s1 = 'kfdsjl'
iter1 = s1.__iter__()
while 1:
    try:
        print(iter1.__next__())
    except StopIteration:
        break

"""
k
f
d
s
j
l
"""

 作业

11,写函数,传入一个参数n,返回n的阶乘
例如:cal(7) 计算7*6*5*4*3*2*1
7+6+...+1
def sum1(n):
    s = 0
    for i in range(n,0,-1):
        s = s + i
    return s
print(sum1(8))  #推到

def sum1(n):
    s = 1
    for i in range(n,0,-1):
        s = s * i
    return s
print(sum1(8))
View Code

 


12写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组(升级题)
例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]

def poker(argv):
    l1 = []
    for num in range(1,14):
        for i in argv:
            l1.append((i,num))
    return l1
print(poker(['黑桃','红心', '草花', '方块']))
View Code

13. def calc(a,b,c,d=1,e=2):
return a+b+c+d+e
# 请分别写出下列标号代码的输出结果,如果出错请写出Error。
print(calc(1,2,3,4,5))  # 15
print(calc(1,2))  # 报错 位置参数一一对应
print(calc(e=4,c=5,a=2,b=3)) # 15
print(calc(1,2,3))  # 9
print(calc(1,2,3,e=4))  # 11
print(calc(1,2,3,d=5,4))  # 15
def extendList(val,list=[]):
    list.append(val)
    return list
list1 = extendList(10)  # [10,]  list
list2 = extendList(123,[]) # [123.]
list3 = extendList('a')  # [10,'a']  list

print('list1=%s'%list1)  # [10,'a']
print('list2=%s'%list2) # [123.]
print('list3=%s'%list3)  # [10,'a']  list


def extendList(val,list=[]):
    list.append(val)
    return list
list1 = extendList(10)
print('list1=%s'%list1)  # [10,]
list2 = extendList(123,[])
print('list2=%s'%list2)  # [123,]
list3 = extendList('a')
print('list3=%s'%list3) # ['a']  [10,'a']
View Code

 动态参数,当时讲有个坑,只要使用默认的参数,那么在内存中使用的就是一个。



 posted on 2022-03-18 16:35  编程之路任重道远  阅读(76)  评论(0)    收藏  举报