• 函数的初识和进阶


    一、函数的初识

    1、为什么要使用函数?

    前言:

    # 重复代码多
    # 可读性差。
    li = [1, 2, 3, 43, 'fdsa', 'alex']
    count = 0
    for i in li:
    count += 1
    print(count)

    s1 = 'fdsgdfkjlgdfgrewioj'

    count = 0
    for i in s1:
    count += 1
    print(count)

    直接结果:
    6
    19

    2、def写len函数
    2.1函数的定义:
    '''
    def 关键字 函数名(设定与变量相同):
    函数体
    '''

    写个跟len相同的函数
    s1 = 'fdsgdfkjlgdfgrewioj'
    def my_len():
    count = 0
    for i in s1:
    count += 1
    print(count)

    my_len() # 函数名+() 执行函数

    2.2 函数的返回值return
    #遇到return,函数结束
    def func1():
    print(11)
    print(22)
    return
    print(333)
    print(444)
    func1()

    执行结果为:
    11
    22

    #给函数的调用者(执行者)返回值。
        无 return 返回None
    return 不写 或者 None 返回None
    return 返回单个数.
    return 返回多个数,将多个数放在元组中返回。

    #return单个返回
    s1='hahahaha'
    def my_len():
    count=0
    for i in s1:
    count+=1
    return 666
    print(my_len(),type(my_len()))
    #return返回多个
    s1='hahahah'
    def my_len():
    count = 0
    for i in s1:
    count += 1
    return 666,222,count,'老男孩'
    print(my_len(),type(my_len()))
    执行结果:(666, 222, 7, '老男孩') <class 'tuple'>

    #
    s1='hhaaha'
    def my_len():
    count=0
    for i in s1:
    count+=1
    return 666,222,count
    ret1,ret2,ret3=my_len() # (666, 222, 19,) 利用分别赋值

    print(ret1)
    print(ret2)
    print(ret3)
    执行结果:

    666
    222
    6

    #这个相当于用函数方式写的len函数
    s1='hahahahah'
    def my_len():
    count = 0
    for i in s1:
    count += 1
    return count
    print(my_len()) #9
    print(len(s1)) #9

    3、函数的传参(形参和实参
    li = [1, 2, 3, 43, 'fdsa', 'alex']
    s1 = 'fdsgdfkjlgdfgrewioj'
    def my_len(a): #函数的定义 ()括号里放的是形式参数,形参
    count=0
    for i in a:
    count+=1
    return count
    ret=my_len(li) #函数的执行 ()括号里放的是实际参数,实参
    print(ret)
    print(len(li))

    执行结果:
    6
    6

    3.1、实参角度分为(位置参数、关键字参数、混合参数)
    #位置参数:必须一一对应,按顺序
    def func1(x,y):
    print(x,y)
    func1(1, 2)
    执行结果:1 2

    #关键字参数:必须一一对应,不分顺序
    def func1(x,y,z):
    print(x,y,z)
    func1(y=2,x=5,z=1)

    直接结果:5 2 1

    练习1:判断a,b ,谁大输出谁
    def max(a,b):
    if a > b:
    return a
    else:
    return b 中间部分可以写成:ret= a if a>b else b ,这个是三元表达式,为什么叫三元表达式,三个变量,ret、a、b
                          return ret
    print(max(100,102)) #102

    以上可以用底下代码实现:
    def max(a,b):return a if a > b else b
    print(max(100,102)) #102

    #混合参数。一一对应且关键字参数必须在位置参数后面
    def func2(argv1,argv2,argv3):
    print(argv1)
    print(argv2)
    print(argv3)
    func2(1,2,argv3=3)
    执行结果:
    1
    2
    3
    3.2、形式角度(位置参数、默认参数、动态参数)
    #位置参数:必须一一对应,按顺序

    def func1(x,y):
    print(x,y)
    func1(1,2) #1 2

    #默认参数:必须在位置参数后面
    def register(name,sex='男'):
    with open('register',encoding='utf-8',mode='a') as f1:
    f1.write('{} {} '.format(name,sex))

    while True:
    username = input('请输入姓名:/q 或者 Q 退出')
    if username.upper() == 'Q':break
    if 'a' in username:
    sex = input('请输入性别:')
    register(username,sex)
    else:
    register(username)
    执行:

    请输入姓名:/q 或者 Q 退出张三
    请输入姓名:/q 或者 Q 退出a丽丽
    请输入性别:女
    请输入姓名:/q 或者 Q 退出Q

    最终register文件中:

    张三 男
    a丽丽 女

    #动态参数 *args ,**kwargs万能参数
    def func2(*args,**kwargs):
        print(args)  #元祖(所有位置参数)
    print(kwargs)
    func2(1,2,3,[1,2,5],'a',name='hha',age=12)
    执行结果:

    (1, 2, 3, [1, 2, 5], 'a')
    {'name': 'hha', 'age': 12}

    ---------------------------------------------------------

    def func3(a,b,*args,sex='男'):
    print(a)
    print(b)
    print(sex)
    print(args)
    func3(1,2,'老男孩','alex','wusir',sex='女') #把默认参数改写了

    执行结果:

    1
    2

    ('老男孩', 'alex', 'wusir')  

    形式参数最终顺序:位置参数,*args,默认参数,**kwargs

    def func3(a,b,*args,sex='男',**kwargs):
    print(a)
    print(b)
    print(sex)
    print(args)
    print(kwargs)
    func3(1,2,'老男孩','alex','wusir',name='alex',age=46)

    执行结果:

    1
    2

    ('老男孩', 'alex', 'wusir')
    {'name': 'alex', 'age': 46}

    ----------------------------------------------

    def func1(*args,**kwargs):  # 函数的定义 * 聚合。
    print(args)
    print(kwargs)
    l1 = [1,2,3,4]
    l11 = (1,2,3,4)
    l2 = ['alex','wusir',4]
    func1(*l1,*l2,*l11) # 函数的执行:* 打散功能


    执行结果:

    (1, 2, 3, 4, 'alex', 'wusir', 4, 1, 2, 3, 4)
    {}

    -------------------------------
    接着上面的:
    func1(1,2,3,4,'alex','wusir',4,1,2,3,4)  # 函数的执行:* 打散功能。
    执行结果:

    (1, 2, 3, 4, 'alex', 'wusir', 4, 1, 2, 3, 4)
    {}

    ----------------------------
    接着最上面的:
    dic1 = {'name1':'alex'}
    dic2 = {'name2':'laonanhai'}
    func1(**dic1,**dic2)

    执行结果:

    ()
    {'name1': 'alex', 'name2': 'laonanhai'}

    二、函数的进阶

    1、
    #临时名称空间:临时名称空间,局部名称空间,存入函数里面的变量与值的关系,随着函数的执行结束,临时名称空间消失。

    #名称空间:全局名称空间,局部名称空间,内置名称空间。
    只要创建.py文件,内置名称空间会加载到内存中。
    #作用域:
    # 全局作用域:全局名称空间,内置名称空间。
    # 局部作用域:局部名称空间

    #加载顺序,取值顺序。
    #加载顺序:内置名称空间 ----> 全局名称空间----> 局部名称空间(函数执行时)
    #取值顺序:局部名称空间 ---> 全局名称空间 ----> 内置名称空间

    name1 = 'wusir'
    def func1():
    print(name1)
    def func2():
    print('****',name1)
    func2()
    func1()
    执行结果:

    wusir
    **** wusir

    -------------------------------------------

    name1 = 'wusir'
    def func1():
    name2 = 'laonanhai'
    print(globals())
    print(locals())
    func1()
    执行结果:

    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000000025DB160>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/PycharmProjects/untitled2/test.py', '__cached__': None, 'name1': 'wusir', 'func1': <function func1 at 0x0000000001CE2E18>}
    {'name2': 'laonanhai'}

     
    #关键字:global nonlocal

    #global 1,声明一个全局变量
    #2,更改一个全局变量
    name = 'wusir'
    def func1():
    global name
    name = 'alex' #把name值更改了
    return
    func1()
    print(name)
    执行结果:alex

    #nonlocal
    def func1():
    name1 = 'alex'
    print('+',name1)
    def inner():
    nonlocal name1
    name1= 'wusir'
    print('*',name1)
    def inner1():
    pass
    inner()
    print('%',name1)
    func1()

    执行结果:

    + alex
    * wusir
    % wusir

     备注:如果不加

     nonlocal name1
    执行结果为:

    + alex
    * wusir
    % alex

    2、函数名

    2.1、可以互相赋值

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

    2.2、函数名可以当成函数的参数
    def func1():
    print(666)
    def func2(argv):
    argv()
    print(777)
    func2(func1)
    执行结果:
    666
    777
    2.3、可以当成容器类数据类型的参数
    def func1():
    print(666)

    def func2():
    print(777)

    def func3():
    print(888)

    l1 = [func1, func2, func3]
    for i in l1:
    i()
    2.4、函数名可以当成函数的返回值
    def func1():
    print(666)

    def func2(argv):
    print(777)
    return argv

    ret = func2(func1)
    ret()
    执行结果:
    777
    666
    3、闭包
    # 闭包 内层函数对外层函数非全局变量的引用,叫做闭包
    #闭包的好处:如果python 检测到闭包
    # 他有一个机制,你的局部作用域不会随着函数的结束而结束。
    def wrapper():
    name1 = '老男孩'
    def inner():
    print(name1)
    inner()
    wrapper() #老男孩

    def wrapper():
    name1 = '老男孩'
    def inner():
    print(name1)
    inner()
    print(inner.__closure__) # cell
    wrapper()
    执行结果:

    老男孩
    (<cell at 0x0000000001E17498: str object at 0x00000000022013F0>,)  出现这种cell的就是闭包

    # 判断是不是闭包,出现None的不是闭包,出现cell那种的才是闭包
    name1 = '老男孩'
    def wrapper():
    def inner():
    print(name1)
    inner()
    print(inner.__closure__) # None
    wrapper()
    执行结果:

    老男孩
    None

    name = 'alex'
    def wrapper(argv):
    def inner():
    print(argv)
    inner()
    print(inner.__closure__) # cell
    wrapper(name)
    执行结果:

    alex
    (<cell at 0x0000000002147498: str object at 0x000000000210B228>,)

    3、小型的网站爬虫

    from urllib.request import urlopen
    def index():
    url = "http://www.cnblogs.com/jin-xin/articles/8259929.html"
    def get():
    return urlopen(url).read()
    return get
    name1 = 'alex'
    content1 = index()()
    content2 = index()()
    print(content1)

    执行结果:
    网站的类似这种的

     3、装饰器

    3.1、
    def wrapper():
    def inner():
    name1 = 'alex'
    print(name1)
    inner()
    wrapper()

    执行结果:alex

    def wrapper():
    def inner():
    name1 = 'alex'
    print(name1)
    return inner
    ret = wrapper() # wrapper() 这个相当于inner
    ret() #alex


    装饰器例子2:
    '''
    # f = func1
    # func1 = timer
    #
    # func1(f) # timmer(func1)
    '''
    # func1 = timer(func1) # inner
    # func1() # inner()
    import time

    # @
    def timer(f1): # f1 = func1
    def inner():
    start_time = time.time()
    f1()
    end_time = time.time()
    print('此函数的执行效率%s' %(end_time-start_time))
    return inner

    @timer # func1 = timer(func1)
    def func1():
    print('晚上回去吃烧烤....')
    time.sleep(0.3)
    @timer # func2 = timer(func2)
    def func2():
    print('晚上回去喝啤酒....')
    time.sleep(0.3)
    func1() # inner()

    执行结果:

    晚上回去吃烧烤....
    此函数的执行效率0.30101704597473145

    #装饰器:在不改变原函数即原函数的调用的情况下,
    # 为原函数增加一些额外的功能,打印日志,执行时间,登录认证等等。
    3.2、被装饰函数带参数
    举例1:
    import time
    def timer(f1): # f1 = func1
    def inner(*args,**kwargs):
    start_time = time.time()
    f1(*args,**kwargs) # func1()
    end_time = time.time()
    print('此函数的执行效率%s' %(end_time-start_time))
    return inner

    @timer # func1 = timer(func1) inner
    def func1(a,b):
    print(a,b)
    print('晚上回去吃烧烤....')
    time.sleep(0.3)
    func1(111,222) # inner(111,222)

    执行结果:

    111 222
    晚上回去吃烧烤....
    此函数的执行效率0.3000171184539795





    举例2:
    import time

    def timer(f1): # f1 = func1
    def inner(*args,**kwargs):
    start_time = time.time()
    ret = f1(*args,**kwargs) # func1()
    end_time = time.time()
    print('此函数的执行效率%s' %(end_time-start_time))
    return ret #如果这个注释掉,返回的666的值就是None
    return inner

    @timer # func1 = timer(func1) inner
    def func1(a,b):
    print(a,b)
    print('晚上回去吃烧烤....')
    time.sleep(0.3)
    return 666
    ret2 = func1(111,222) # inner(111,222)
    print(ret2)

    执行结果为:

    111 222
    晚上回去吃烧烤....
    此函数的执行效率0.3080177307128906
    666

    装饰器总结:

    def wrapper(f1):
    def inner(*args,**kwargs):
    '''执行函数之前的操作'''
    ret = f1(*args,**kwargs)
    '''执行函数之后的操作'''
    return ret
    return inner

    @wrapper
    def func1():
    print(222)
    return 333
    print(func1())

    执行结果:
    222
    333



    作业:
    1),启动程序,首页面应该显示成如下格式:
    欢迎来到博客园首页
    1:请登录
    2:请注册
    3:文章页面
    4:日记页面
    5:评论页面
    6:收藏页面
    7:注销
    8:退出程序
    2),用户输入选项,3~6选项必须在用户登录成功之后,才能访问成功。
    3),用户选择登录,用户名密码从register文件中读取验证,三次机会,没成功则结束整个程 序运行,成功之后,
    可以选择访问3~6项.
    4),如果用户没有注册,则可以选择注册,注册成功之后,可以自动完成登录,然后进入首页选择。
    5),注销用户是指注销用户的登录状态,使其在访问任何页面时,必须重新登录。
    6),退出程序为结束整个程序运行。

    '''
     












     
    
    





     
     








































  • 相关阅读:
    将1、2、3、……、n这n个连续自然数分成g组,使每组的和相等。g组中个数最多的一组有几个?
    磁带机、驱动器、磁带库、机械手之间的区别
    Mysql基础命令
    pip 加速下载
    NBU命令之 nbftconfig :配置与光纤传输 (FT) 服务器和 SAN 客户端相关的属性
    IEDriverServer.exe驱动问题汇总
    系统集成项目管理工程师考试2020介绍
    LTO1,LTO2,LTO3,LTO4,LTO5 LTO6 磁带读写速度和兼容性及LTO6主要参数
    Mysql 备份方式 MySQL Agent & MySQL Enterprise Backup & Percona XtraBackup
    Netbackuk命令之bpclntcmd
  • 原文地址:https://www.cnblogs.com/lucky-penguin/p/8883364.html
Copyright © 2020-2023  润新知