首页 > 代码库 > 函数详解day04

函数详解day04

目录

1.函数对象:函数是第一类对象,即函数可以当做数据被传递... 1

2.函数的嵌套调用:在一个函数内部调用其他函数... 1

3.函数的嵌套定义:... 1

4.名称空间与作用域... 1

5.闭包函数:内部函数包含对外部作用而非全局作用域的引用,该内部函数就是闭包函数     2

 

1.函数对象:函数是第一类对象,即函数可以当做数据被传递

         1.可以被引用

         2.可以当做参数传递

         3.返回值可以是函数

         4.可以当做容器类型的元素

2.函数的嵌套调用:在一个函数内部调用其他函数

3.函数的嵌套定义:

def f1():

    def f2():

        print(‘f2‘)

        def f3():

            print(‘f3‘)

f1()

执行结果:什么都没有,因为只是定义了,没有调用f2

def f1():

    def f2():

        print(‘f2‘)

        def f3():

            print(‘f3‘)

        f3()

    f2()

f1()

输出结果:f2,f3

4.名称空间与作用域

全局作用域:内置名称空间,全局名称空间

局部作用:局部名称空间

变量查找顺序:局部->全局->内置

x = 1000

def func(y):

    x=2

    print(locals())#打印局部变量

    print(globals())#打印全部变量

func(1)

输出结果:

{‘x‘: 2, ‘y‘: 1}

{‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x0000000000657B38>, ‘__spec__‘: None, ‘__name__‘: ‘__main__‘, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__doc__‘: None, ‘__package__‘: None, ‘x‘: 1000, ‘__file__‘: ‘D:/kinggsoft/python_file/day04/day04.py‘, ‘__cached__‘: None, ‘func‘: <function func at 0x0000000000711400>}

5.闭包函数:内部函数包含对外部作用而非全局作用域的引用,该内部函数就是闭包函数

def f1():

    x = 1#外部非全局变量

    def f2():

        print(x)

    return f2

res = f1()#返回f2地址

res()

函数外面包了一层函数,用来控制变量作用域

6.装饰器:

usr_info={‘username‘:None,‘state‘:False}

def auth(a):

    def auth2(func):

        def wrapper(*args,**kwargs):

            if args[0] ==‘dodo‘ and args[1] == ‘111‘:

                func(*args,**kwargs)

                usr_info[‘username‘]=args[0]

                usr_info[‘state‘]=True

 

            if a == ‘dodo‘:

                print(‘supper manger‘)

            elif a:

                print(‘ussall‘)

            return wrapper

    return auth2

 

@auth(adapt)#welcom=auth(welcome)

def welcome(name,pwd):

    print(‘welcome,%s‘ %(name))

 

while True:

    name =input(‘name:‘)

    pwd = input(‘pwd‘)

    a=welcome(name, pwd)

    if a ==1:

        break

 

6.装饰器:装饰别人的工具,修饰->添加功能,工具->函数

装饰器本身可能是任何可调用对象,函数(还有类)

被装饰对象也可能是任意可调用对象

为什么要用装饰器:对修改是封闭的,对扩张是开放的

装饰器就是为了在不修改源代码和函数调用方式的前提下,为其添加新功能

import time

def f(func):

    def timmer(*args):

        start = time.time()

        func(*args)

        end = time.time()

        print(‘time:%s‘ %(end-start))

    return timmer

 

 

@f#hello=timmer(hello)

def hello(name):

    time.sleep(3)

    print(‘hello!%s‘ %(name))

 

hello(‘egon’)

输出结果:

hello!egon

time:3.000171422958374

7.有参装饰器

#有参装饰器

def auth(driver):

    def login(func):

        def wrapper(*args,**kwargs):

            if driver == ‘file‘:

                if args[0]==‘dodo‘ and args[1] ==‘123‘:

                    a=func(*args,**kwargs)

                    return 1

                else:

                    print(‘请输入正确的账号密码!‘)

            else:

                print(‘不识别的驱动‘)

        return wrapper

    return login

@auth(‘file‘)

def welcome(name,pwd):

    print("*************welcome*************")

    print("*************%s*************" %name)

    return 1

while True:

    name = input(‘name:‘)

    pwd = input(‘pwd:‘)

    a=welcome(name,pwd)

    if a == 1:

        break

8.多层装饰器嵌套

import time

def timmer(func):

    def wrapper(*args,**kwargs):

 

        start=time.time()

        time.sleep(3)

        func(*args,**kwargs)

        end=time.time()

        print(‘time:%s‘ %(end-start))

                   return 1

    return wrapper

def login(func):#login = auth(login)

    def wrapper(*args,**kwargs):

        start = time.time()

        time.sleep(3)

        if args[0]==‘dodo‘ and args[1] ==‘123‘:

            a=func(*args,**kwargs)

            end = time.time()

            print(‘logintime:%s‘ % (end - start))

            return 1

        else:

            print(‘请输入正确的账号密码!‘)

    return wrapper

@timmer

@login

def welcome(name,pwd,driver):

    print("*************welcome*************")

    print("*************%s*************" %name)

    return 1

while True:

    name = input(‘name:‘)

    pwd = input(‘pwd:‘)

    a=welcome(name,pwd,‘file‘)

    if a == 1:

        break

输出结果:

name:dodo

pwd:123

*************welcome*************

*************dodo*************

logintime:3.000171661376953

time:6.000343322753906

9.迭代器

重复的过程称为迭代,每次迭代都是下次迭代的初始值

为什么要用迭代器:对于没有索引的数据类型,必须提供一种不依赖于索引的迭代方式

只要数据类型下有__iter__()方法就是可迭代的,执行iter方法得到的结果就是迭代器

i=[1,2,3,4].__iter__()

print(i)

print(i.__next__())

输出结果:

<list_iterator object at 0x0000000000A70278>

1

通过next方法遍历

对字典的遍历,只能取到key,取不到val

i={‘bb‘:2,‘aa‘:4}.__iter__()

print(i)

 

print(i.__next__())

输出结果

<dict_keyiterator object at 0x00000000011C5408>

bb

用迭代器遍历字典

dic ={‘bb‘:2,‘aa‘:4}
i=dic.__iter__()
print(i)
while True:
    val=i.__next__()
    print(dic[val])

输出结果

Traceback (most recent call last):

  File "D:/kinggsoft/python_file/day04/day04.py", line 187, in <module>

    val=i.__next__()

StopIteration

<dict_keyiterator object at 0x0000000001195408>

4

2

如何判断一个对象是可迭代的对象,还是迭代器对象

from collections import Iterable,Iterator

‘abc‘.__iter__()
[].__iter__()
{}.__iter__()
{‘a‘:1}.__iter__()
(1,).__iter__()
with open(‘ceshi.py‘) as f :
    f.__iter__()
print(isinstance(‘aa‘,Iterable))
print(isinstance(‘aa‘,Iterator))

输出结果:

True

False

可迭代对象只有iter方法,

迭代器有next和iter方法

迭代协议:

对象有__next__方法

对象有__iter__对于迭代器对象来说,迭代器执行__iter__方法得到的还是迭代器本身,

for循环,enumerate也是迭代器

#for循环
dic = {‘name‘:‘lili‘,‘age‘:18}
for i in dic:#k=iter(dic) i=next(k)
   
print(i)

相当于
i=iter(dic)
while True:
    try:
        k=next(i)
        print(k)
    except StopIteration:
        break

迭代器的有点和缺点

有点

  1. 提供了不依赖下标的迭代方式
  2. 就迭代器本身来说更节省内存

缺点

  1. 没有序列不灵活
  2. 无法获取长度

10.生成器

生成器函数:只要函数体包含yeild关键字,该函数就叫做生成器函数

吧函数变成了迭代器

ps:只要函数中有yield,就加括号不会执行函数,而是把函数变成迭代器

yield

#yeild

def foo():

    yield 1

    yield 2

    yield 3

g=foo()

print(g)

print(next(g))

print(next(g))

print(next(g))

输出结果:

1

2

3

 

def foo():

    print(‘one‘)

    yield 1

    print(‘two‘)

    yield 2

    print(‘three‘)

    yield 3

g=foo()

print(g)

res=print(next(g))

输出结果

<generator object foo at 0x00000000006A1BF8>

one

1

yield:功能

  1. 相当于为函数封装好iter和next方法
  2. return 只能返回一次值

yield返回多次值

 #tail -f |grep ‘python‘
def tail():
    import time
    with open(与铁林,‘r+‘) as f:
        f.seek(0, 2)  # 跳到文件末尾
       
while True:

            line = f.readline()
            if line:
                if ‘python‘ in line:
                    yield line
            else:
                time.sleep(0.2)
a=tail()
print(next(a))

 

程序执行结果

直到文件有新内容输入保存为止

内置函数

  1. abs——绝对值
  2. all——对所有值进行bool值判断,如果是返回true

all([1,2,3])=ètrue

  1. any——只要一个是true就是true,空也是false
  2. bin——十进制转为二进制
  3. hex——十进制转为十六进制
  4. oct——十进制转为八进制
  5. chr——ASCII转为字符
  6. ord——字符转为ASCII
  7. complex——复数
  8. 工厂函数——dict、int、list、str、set
  9. dir——查看属性
  10. divmod(100,3)——打印输出(33,1)主要是分页功能
  11. eval——把字符串里的内容提取出来执行

cmd=‘print(‘哈哈哈’)’

eval(cmd)

  1. frozenset——定义不可变集合
  2. hash——主要做校验,是一种算法
    1. 只要校验内容一致,hash也是一样的
    2. 不可逆:不能根据hash值退回原值
    3. 只要采用hash算法一样的,不论被校验的内容多长,hash一样长
  3. id——看对象的身份
  4. is——身份运算符

x=1

y=x

print(id(x),id(y))=è得到的值是一样的

print(x is y)èTrue

  1. max——最大值
  2. pow——pow(10,2,3)è10的平方%3
  3. reverse——反转,反转返回的是一个迭代器,不会影响原值

l=[‘a‘,2,4]
a=reversed(l)
print(a)
print(reversed(l))
print(list(reversed(l)))
print(l)

输出结果:

<list_reverseiterator object at 0x0000000000820278>

<list_reverseiterator object at 0x0000000000820470>

[4, 2, ‘a‘]

[‘a‘, 2, 4]

超级重点:

l=[‘a‘,2,4]

a=reversed(l)

for i in a:

    print(i)

print(reversed(a))

输出结果:

Traceback (most recent call last):

  File "D:/kinggsoft/python_file/day04/day04.py", line 244, in <module>

    print(reversed(a))

TypeError: argument to reversed() must be a sequence

4

2

a

因为for已经把迭代器走完

  1. round——保留小数,默认两位,四舍五入
  2. slice——切片
  3. vars——如果不加参数同locals查看局部变量
  4. zip——一一对应

s=‘hello‘
l=[1,2,3,4,5,6,7]
z=zip(s,l)è迭代器
print(z)
for i in z:
    print(i)

输出结果:

<zip object at 0x00000000007669C8>

(‘h‘, 1)

(‘e‘, 2)

(‘l‘, 3)

(‘l‘, 4)

(‘o‘, 5)

函数详解day04