• third day -- 02--函数


    复习

     1 # 函数
     2     # 定义
     3         # 关键字 def 函数名(形参):
     4         # 参数 :
     5             # 位置参数
     6             # *args  动态传参 :接收在调用的时候传过来的多余的所有按位置传的参数
     7             # 关键字参数 默认参数,如果不传会有一个默认的值,如果传了会覆盖默认的值
     8             # **kwargs  动态传参 :接收在调用的时候传过来的多余的所有按关键字传的参数
     9         # 返回值
    10             # return 停止一个程序的运行,返回参数
    11                 # 没有返回值 默认返回None
    12                 # 有一个返回值
    13                 # 返回多个值
    14     # 调用
    15         # 调用的关键字 函数名(实参)
    16         # 传参数 :
    17             # 按照位置传
    18             # 按照关键字传
    19         # 接收返回值
    20             # 没有返回值 不接受
    21             # 有一个返回值 用一个变量接收
    22             # 有多个返回值
    23                 # 用一个变量接收 所用返回值都会被组织成一个元组
    24                 # 用多个变量接收 有多少个返回值 就必须用多少个变量接收
    25 # 函数是第一类对象的概念
    26     # 函数名 --> 函数的内存地址
    27     # 函数名可以作为 容器类型的元素 函数的参数、返回值 还能进行赋值  --> 变量
    28 
    29 # 闭包和装饰器
    30     # 闭包的定义 : 内部函数引用外部函数的变量
    31     # 闭包的应用 :装饰器
    View Code

    1,函数的初识。
    函数的定义,函数体,函数名。

    函数的返回值return。

    函数的参数。
    实参:
    三种

    形参:
    三种。
    动态参数。


    #一、函数概念
    1.未引入函数时:代码重复;可读性差
     1 # li = [1, 2, 3, 43, 'fdsa', 'alex']
     2 # count = 0
     3 # for i in li:
     4 #     count += 1
     5 # print(count)
     6 #
     7 # s1 = 'fdsgdfkjlgdfgrewioj'
     8 #
     9 # count = 0
    10 # for i in s1:
    11 #     count += 1
    12 # print(count)
    View Code

    2.def 函数名 (): #函数名定义与变量相同
    函数体
    3.函数名+() 执行函数
    4.print(len(s1)) 未调用函数,打印长度
    5.函数中一般不加print
    6.函数的返回值:
    return
    1.遇到return,函数结束 与break相似
    def func1():
            print(11)
            return
            print(22)
        func1()
    return结束函数

    2.给函数的调用者(执行者)提供返回值 #函数调用者:函数名()整体
    1.无return返回None
    s1='lijie123456'
    def my_len():
        count=0
        for i in s1:
            count+=1
    print(my_len())  #None
    View Code

    2.return不写或者None 返回None
    3.return返回单个数
    s1='lijie123456'
    
    # def my_len():
    #     count=0
    #     for i in s1:
    #         count+=1
    #     return 666
    # print(my_len(),type(my_len()))   #666 <class 'int'>
    返回单个数

    4.return返回多个数将放在元祖中返回
    s1='lijie123456'
    # def my_len():
    #     count=0
    #     for i in s1:
    #         count+=1
    #     return 666,count,'丽姐'
    # print(my_len(),type(my_len()))  #(666, 11, '丽姐') <class 'tuple'>
    多个数

    5:return分别赋值功能!!!
    s1='lijie123456'
    # def my_len():
    #     count=0
    #     for i in s1:
    #         count+=1
    #     return 666,222,count
    # ret1,ret2,ret3=my_len() (666,222,11)
    # print(ret1) #666
    # print(ret2) #222
    # print(ret3)  #11
    分别赋值

    基本实现了等同于len的功能,但s1改变,for循环中in后就要改变,引入参数的概念
    s1='123'
    # def my_len():
    #     count = 0
    #     for i in s1:
    #         count += 1
    #     return count
    # print(my_len())
    # print(len(s1))
    不含参数

    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(s1))
    函数的传参

    二、参数传值方法

    我们告诉mylen函数要计算的字符串是谁,这个过程就叫做 传递参数,简称传参,我们调用函数时传递的这个“hello world”和定义函数时的s1就是参数。
    
    实参与形参
    
    参数还有分别:
    
    我们调用函数时传递的这个“hello world”被称为实际参数,因为这个是实际的要交给函数的内容,简称实参。
    
    定义函数时的s1,只是一个变量的名字,被称为形式参数,因为在定义函数的时候它只是一个形式,表示这里有一个参数,简称形参。 
    
    传递多个参数
    
    参数可以传递多个,多个参数之间用逗号分割。
    实参形参理解
    '''
    从实参角度:
    1.位置参数 必须一一对应,按顺序
    def f(x,y):
        print(x,y)
    f(1,2)
    View Code

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

    #输出最大值

    def max_number(x,y):  #注意传值
        if x>y:
            return x
        else:
            return y
    print(max_number(110,1))
    
    #三元运算符
    
    def max(a,b):
        ret=a if a>b else b
        #print(ret)
    print(max(1,2))  #为什么结果为None??max中无返回值
    
    正确写法:
    def max(a,b):
        return a if a>b else b
    print(max(1,2))
    View Code

    3.混合参数:一一对应且关键字参数在位置参数后
    # def func2(argv1,argv2,argv3):
    #     print(argv1)
    #     print(argv2)
    #     print(argv3)
    # func2(1,2,argv3=4)
    View Code


    从形参角度
    1.位置参数 同实参,必须一一对应,按顺序
    # def func1(x,y):
    #     print(x,y)
    # func1(1,2)
    View Code

    2.默认参数 必须在位置参数后面
     1 # def regedit(name,sex):
     2 #     with open('regedit',encoding='utf-8',mode='a') as f1:
     3 #         f1.write('{} {}
    '.format(name,sex))
     4 #
     5 # while True:
     6 #     name=input('请输入名字:/q 或Q退出')
     7 #     if name.upper()=='Q':break
     8 #     sex=input('请输入性别;')
     9 #     regedit(name,sex)
    10 # #默写加默认参数
    11 def regedit(name,sex='male'):
    12     with open('regedit',encoding='utf-8',mode='a')as f1:
    13         f1.write('{} {} 
    '.format(name,sex)) #注意) 的位置
    14 while True:
    15     name=input('请输入名字:/q或Q退出')
    16     if name.upper()=='Q':break
    17     if 'a' in name:
    18         sex=input('请输入性别:')
    19         regedit(name,sex)
    20     else:
    21         regedit(name)
    默认参数

    3.动态参数 *args,**kwargs 万能参数
    *args元祖(所有位置参数) **kwargs字典(所有关键字参数)
    def func2(*args,**kwargs):
        print(args)
        print(kwargs)
    func2(1,2,3,4,5,6,7,11,'alex','老男孩',a='ww',b='qq',c='222')
    
    #(1, 2, 3, 4, 5, 6, 7, 11, 'alex', '老男孩')
    #{'a': 'ww', 'b': 'qq', 'c': '222'}
    View Code

    三种类型顺序:位置参数---*args----默认参数---**kwargs
    def func3(a,b,*args,sex='',**kwargs):
        print(a)
        print(b)
        print(sex)
        print(args)
        print(kwargs)
    func3(1,2,'老男孩','alex','wusir',sex='n',name='alex',age=46)
    # 1
    # 2
    # n
    # ('老男孩', 'alex', 'wusir')
    # {'name': 'alex', 'age': 46}
    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)  # 函数的执行:* 打散功能。
    # # func1(1,2,3,4,'alex','wusir',4,1,2,3,4)  # 函数的执行:* 打散功能。
    dic1 = {'name1':'alex'}
    dic2 = {'name2':'laonanhai'}
    func1(dic1,dic2)    #({'name1': 'alex'}, {'name2': 'laonanhai'})  /{}
    
    func1(*dic1,**dic2) 
    #('name1',)
    #{'name2': 'laonanhai'}
    
    func1(**dic1,**dic2)  
    #()
    #{'name1': 'alex', 'name2': 'laonanhai'}
    View Code
    
    

    2,函数的进阶。
    名称空间,全局名称空间,局部名称空间,内置名称空间,
    作用域。
    globals locals
    global,nonlocal
    作用域链。
    函数的名字。
    闭包。

    '''
    函数的进阶
    1.名称空间:
    全局名称空间
    局部名称空间
    内置名称空间
    2.作用域
    全局作用域:全局名称空间和内置名称空间
    局部作用域:作用于局部名称空间
    3.加载顺序:内置名称空间--全局名称空间--局部作用空间(函数执行时)
    取值顺序:局部名称空间---全局名称空间---内置名称空间
    # name = 'alex'
    # age = 12
    # def func1():
    #     name1 = 'wusir'
    #     age1 = 34
    # func1()
    # print(name1)  #会报错,name1没有被定义
    #临时名称空间:临时名称空间,局部名称空间,存入函数里面的变量与值的关系,随着函数的执行结束,临时名称空间消失。
    
    #名称空间:全局名称空间,局部名称空间,内置名称空间。
    #作用域:
        # 全局作用域:全局名称空间,内置名称空间。
        # 局部作用域:局部名称空间
    
    #加载顺序,取值顺序。
    #加载顺序:内置名称空间 ----> 全局名称空间----> 局部名称空间(函数执行时)
    #取值顺序:局部名称空间 ---> 全局名称空间 ----> 内置名称空间
    # name1 = 'wusir'
    # def func1():
    #     print(name1)
    #     def func2():
    #         print('****',name1)
    #     func2()
    # func1()
    
    # name1 = 'wusir'
    # def func1():
    #     name2 = 'laonanhai'
    #     print(globals()) #所有的方法{'__name__': '__main__', '__doc__': "
    文件
    操作文件
    1.文件路径
    2.编码方式
    3,动作mode
    
    代码
    # f1 = open('D:\空姐护士老师主妇.txt', encoding='utf-8', mode='r')
    # content = f1.read()
    # print(content)
    # f1.close()
    解释
     1,打开文件,产生文件句柄。
     2,操作文件句柄。
    3.关闭文件!!
    
    ", '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001DCA208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:/Users/venv/third day/0415课上笔记.py', '__cached__': None, 's1': 'lijie123456', 'name1': 'wusir', 'func1': <function func1 at 0x0000000001D22EA0>}
    #     print(locals()) #查看本地的方法{'name2': 'laonanhai'}
    # func1()
    View Code

    4.关键字 global nonlocal
    局部名称变量可以引用全局变量,但不能做改变,会报错;要用到关键字
    1 name = 'alex'
    2 age = 12
    3 def func1():
    4     global name1
    5     name1= 'wusir'
    6     age1 = 34
    7 func1()
    8 print(name1)
    View Code


    global
    1.声明全局变量
    2.更改全局变量
    fun1() 执行函数!
    #关键字:global nonlocal
    # count = 1
    # def func1():
    #     count = count + 1
    #     print(count) #未执行,执行会报错
    #global 1,声明一个全局变量
           #2,更改一个全局变量
    # name = 'wusir'
    # def func1():
    #     global name
    #     name = 'alex'
    #     return  #在此处写不写都可以
    # func1()
    # print(name)  #alex
    View Code

    nonlocal 用处少,改变局部变量
      1,不能修改全局变量。
      2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
    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

    5.函数名
    1.可以互相赋值
    # def func1():
    #     print(666)
    #
    # f1 = func1
    # f1()
    View Code

    2.函数名可以当成函数的参数
    def func1():
        print(666)
    def func2(argv):
        argv()
        print(777)
    func2(func1)
    View Code

    3.可以当成容器类 数据类型的参数
    # def func1():
    #     print(666)
    #
    # def func2():
    #     print(777)
    #
    # def func3():
    #     print(888)
    #
    # l1 = [func1, func2, func3]
    # for i in l1:
    #     i()
    View Code

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

    777 666!!!
    加()就执行
    def func1():
        print(666)
    def func2(argv): 
        print(777)
        return argv  #func1()
    
    ret = func2(func1)
    ret() #执行func2(func1)
    View Code

    方法,查看全局变量、局部变量,返回在字典中
    globals()
    locals()



    #执行inner函数
    # def wrapper():
    #     def inner():
    #         name1 = 'alex'
    #         print(name1)
    #     inner()
    # wrapper()
    
    # #练习理解
    def wrapper():
        def inner():
            name1 = 'alex'
            print(name1)
        return inner   #相当于inner()
    ret=wrapper()
    ret()
    执行inner的两种方法
    ret=wrapper() #inner

    6.闭包:内层函数对外层函数非全局变量的引用
    1.判断是不是闭包
    函数名.__closure__ #None 不是 cell是

    一般会有面试题
    闭包的好处:如果python检测到闭包,它有一个机制,
    局部作用域不会随着程序的结束而结束
    # 闭包 内层函数对外层函数非全局变量的引用,叫做闭包
    #闭包的好处:如果python 检测到闭包,
    # 他有一个机制,你的局部作用域不会随着函数的结束而结束。
    
    # def wrapper():
    #     name1 = '老男孩'
    #     def inner():
    #         print(name1)
    #     inner()
    #     print(inner.__closure__)  # cell
    # wrapper()
    # 判断是不是闭包
    # name1 = '老男孩'
    # def wrapper():
    #     def inner():
    #         print(name1)
    #     inner()
    #     print(inner.__closure__)  # None
    # wrapper()
    
    # name = 'alex'
    # def wrapper(argv):
    #     def inner():
    #         print(argv)
    #     inner()
    #     print(inner.__closure__)  # cell
    # wrapper(name)
    View Code

    index()() #第一个()返回return get,再加一个()执行get
    一般用于爬虫、装饰器
    有回收机制
    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()()  #第一个()返回return get,再加一个()执行get
    # content2 = index()()
    # print(content1)
    爬虫小例子

    '''

    3,装饰器。

    '''
    装饰器
    1.梳理调用inner例子--最简单版的装饰器
    2.语法糖 @

    在不改变原函数即原函数的调用的情况下,为原函数登录增加一些特殊功能,打印日志、执行时间、登录认证
     1 import time
     2 def func1():
     3     print('晚上回去吃烧烤....')
     4     time.sleep(0.5)
     5 
     6 def timer(f1):  # f1 = func1
     7     def inner():
     8         start_time = time.time()
     9         f1()
    10         end_time = time.time()
    11         print('此函数的执行效率%s' %(end_time-start_time))
    12     return inner
    13 #方法1
    14 # f1=func1
    15 # func1=timer
    16 # func1(f1)()  #timmer(func1)
    17 #方法2
    18 # func1=timer(func1) #inner
    19 # func1()  #inner()
    20 #方法3
    21 @timer
    22 def func1():
    23     print('晚上回去吃烧烤....')
    24     time.sleep(0.5)
    25 func1()
    View Code

    3.带参数的装饰器
    两个* **
     1 import time
     2 # def wrapper():
     3 #     def inner():
     4 #         name1 = 'alex'
     5 #         print(name1)
     6 #     inner()
     7 # wrapper()
     8 
     9 # def wrapper():
    10 #     def inner():
    11 #         name1 = 'alex'
    12 #         print(name1)
    13 #     return inner
    14 # ret = wrapper()  # inner
    15 # ret()
    16 def func1():
    17     print('晚上回去吃烧烤....')
    18     time.sleep(0.3)
    19 
    20 def func2():
    21     print('晚上回去喝啤酒....')
    22     time.sleep(0.3)
    23 
    24 # 最简单版的装饰器
    25 # def timer(f1):  # f1 = func1
    26 #     def inner():
    27 #         start_time = time.time()
    28 #         f1()
    29 #         end_time = time.time()
    30 #         print('此函数的执行效率%s' %(end_time-start_time))
    31 #     return inner
    32 '''
    33 # f = func1
    34 # func1 = timer
    35 #
    36 # func1(f)  # timmer(func1)
    37 '''
    38 # func1 = timer(func1)  # inner
    39 # func1()  # inner()
    40 
    41 
    42 # @
    43 def timer(f1):  # f1 = func1
    44     def inner():
    45         start_time = time.time()
    46         f1()
    47         end_time = time.time()
    48         print('此函数的执行效率%s' %(end_time-start_time))
    49     return inner
    50 
    51 @timer  # func1 = timer(func1)
    52 def func1():
    53     print('晚上回去吃烧烤....')
    54     time.sleep(0.3)
    55 @timer # func2 = timer(func2)
    56 def func2():
    57     print('晚上回去喝啤酒....')
    58     time.sleep(0.3)
    59 func1()  # inner()
    60 func2()  # inner()
    View Code
     1 #装饰器:在不改变原函数即原函数的调用的情况下,
     2 # 为原函数增加一些额外的功能,打印日志,执行时间,登录认证等等。
     3 
     4 #被装饰函数带参数
     5 # def timer(f1):  # f1 = func1
     6 #     def inner(*args,**kwargs):
     7 #         start_time = time.time()
     8 #         f1(*args,**kwargs)  # func1()
     9 #         end_time = time.time()
    10 #         print('此函数的执行效率%s' %(end_time-start_time))
    11 #     return inner
    12 #
    13 # @timer  # func1 = timer(func1)  inner
    14 # def func1(a,b):
    15 #     print(a,b)
    16 #     print('晚上回去吃烧烤....')
    17 #     time.sleep(0.3)
    18 # func1(111,222)  # inner(111,222)
    19 
    20 #被装饰函数带参数
    21 # def timer(f1):  # f1 = func1
    22 #     def inner(*args,**kwargs):
    23 #         start_time = time.time()
    24 #         ret = f1(*args,**kwargs)  # func1()
    25 #         end_time = time.time()
    26 #         print('此函数的执行效率%s' %(end_time-start_time))
    27 #         return ret
    28 #     return inner
    29 #
    30 # @timer  # func1 = timer(func1)  inner
    31 # def func1(a,b):
    32 #     print(a,b)
    33 #     print('晚上回去吃烧烤....')
    34 #     time.sleep(0.3)
    35 #     return 666
    36 # ret2 = func1(111,222)  # inner(111,222)
    37 # print(ret2)
    带参数
    结构:
    def wrapper(f1):
        def inner(*args,**kwargs):
            '''执行函数之前的操作'''
            ret = f1(*args,**kwargs)
            '''执行函数之后的操作'''
            return ret
        return f1
    
    # @wrapper
    # def func1():
    #     print(222)
    #     return 333
    # print(func1())
    

      



    '''


    4,装饰器的进阶。

  • 相关阅读:
    Oracle 导入导出 创建用户等
    如何导出 Windows EventLog
    QT connect 的信号,不能写类名
    Easylogging
    Openstack Swift SLO & bulk delete 测试常用命令,文件等
    Openstack Swift Static Large Object (SLO)
    Linux 创建指定大小的文件
    Openstack Swiftclient 查看 log
    Openstack Swift 批量删除 (bulk delete)
    winsock server 示例代码中 shutdown 的选项
  • 原文地址:https://www.cnblogs.com/lijie123/p/8856886.html
Copyright © 2020-2023  润新知