• 函数


     
    函数
    可读性强 复用性强
    def 函数名():
    函数体
    return 返回值
    函数名() 调用函数不接受返回值; 函数名就是函数的内存地址,加上括号就等于调用了
    返回值 = 函数名() # 接受返回值
    所有的函数 只定义不调用就一定不执行
    要先定义后调用
    # 定义函数
     def mylen(s):  # 定义一个函数 在这里s是形参
         n = 0
         for i in s:
             n += 1
         return n    # 返回值
     mylen()  #  调用函数
     print(mylen('dfgsdf'))   # 这里里面的值是实参
     
    
    
    '''
    返回值 #
    没有返回值:默认返回None
        不写return 函数内的代码执行完毕自动结束
        只写return 结束一个函数
        或 return None
    可以返回一个值:结束了函数且返回一个值,可以是任意的值
        return value
    可以返回多个值:多个值之间用逗号隔开,接受的时候可以用一个变量接受(元祖),也可以用等量的多个变量接收
        return ...
    参数

    形参:定义函数的时候
      实参:调用函数的时候
        没有参数
    定义和调用的时候括号里不写内容
    有一个参数
    传什么就是什么
    有多个参数
       站在实参角度
    按照位置传参
    按照关键字传参
    混着传参 位置传参>关键字传参
    不能给同一个参数传多个值
    站在形参
    位置传参:必须传,且有几个参数就传几个值
    默认参数:可以不传,就用默认的,如果传了实参,就用实参
    动态参数:可以任意接受多个参数
    参数名前加* , 习惯参数名*args :接受的是按照位置传参的值,组织成一个元祖
    全部不知多少的关键字传参:**kwargs :接受的是按照关键字传参的值,组织成一个字典
    def func(*args,**kwargs) 既可以接受位置又可以关键字 ,顺序不可互换
    顺序: 位置参数 > *args > 默认参数 > **kwargs
    def func(*args):   # 站在形参的角度上,给变量加上*,就是组合所有传来的值
        print(args)
    
    l = [1,2,3,4,5]
    func(*l)  # 站在实参的角度上,给一个序列加上*,就是将这个序列按照顺序分各个元素
    
    def func2(**kwargs):
        print(kwargs)
    
    d = {'a':1,"b":2}
    func2(**d)  # 同样 **d
    
    
    # 函数的注释
    def func():
        '''
        这个函数实现了什么功能
        参数1:
        参数2:
        return:是字符串或者列表的长度
        '''
        pass
    # 默认陷阱
    def fun(l = []):   # 当参数是个可变数据类型,那么每一次调用函数的时候,如果不传值就公用这个数据类型的资源
        l.append()
        print(l)
    命名空间



    内置命名空间:python解释器
    就是python解释器启动就可以使用的名字储存空间
    内置的名字在启动解释器的时候被加载进内存里
    eg:print()
    全局命名空间:我们写的代码但不是函数中的代码
    是在程序从上到下被执行的过程中依次加载进内存的
    放置了我们设置的所有变量名和函数名
    局部命名空间:函数
    就是函数内部定义的名字
    当调用函数的时候 才会产生这个名称空间,随着函数执行结束,这个命名空间就又消失了

    在局部:可以使用全局,内置
    在全局:可以使用内置 但不能使用局部
    在内置:不能使用全局和局部
    依赖倒置原则

    在正常情况下,直接使用内置的名字
    当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字
    如果没有就找上一级要,上级没有在找上一级要,如果内置的名字空间都没有,就会报错
    多个函数应该拥有多个独立的局部名字空间,不互相共享

    作用域
    全局作用域 -->内置和全局名字空间中的名字都属于全局作用域 -- globals()查看
    局部作用域 -->函数 局部命名空间中的名字属于局部作用域 -- locals()查看
    a = 1   # 这个定义在全局
    def func():
        global a
        a += 1
        
    print(a)
    print(globals()) # 永远打印全局的名字
    print(locals())  # 本地的  输出什么 根据locals所在的位置

    对于不可变数据类型 在局部可查看局部作用域中的变量,但不能直接修改
    如果想要修改 需要在程序的一一开始添加global声明 谨慎使用会让 代码不安全
    如果在一个局部内声明一个global变量,那么这个变量在局部的所有操作将对全局的变量有效
    nonlocal 只能用于局部变量 找上层中离当前函数最近一层的局部变量

    def max(a,b):
        return a if a>b else b
    
    def the_max(x,y,z):  # 函数嵌套调用
        c = max(x,y)
        return max(c,z)
    
    print(the_max(1,2,3))
    # 函数嵌套定义
    # 内部函数可以使用外部函数变量
    def outer():
        a = 1
        def inner():
            b = 2
            print(a)
            def inner1():
    
                nonlocal a # 声明了一个上层局部的第一个变量
                a = a+1
                print(b)
            inner1()
        print(a)
        inner()
    outer()
    def func():
        print(123)
    
    # func() # 函数名就是内存地址
    func2 = func  # 函数名可以赋值
    func2()
    
    l = [func,func2] # 函数名可以作为容器类型的元素
    print(l)
    for i in l:
        i()
    
    def hel(f):
        f()
        return f   # 函数名可以作为函数的返回值
    hel(func)  # 函数名可以作为函数的参数
    v = hel(func)
    v()
    # 闭包 :嵌套函数,内部函数调用外部函数的变量
    def outer():
        a = 1
        def inner():
            print(a)
        print(inner.__closure__)
        return inner  # 我返回这个函数值
    outer()
    print(outer.__closure__)
    
    inn = outer() # 全局的变量指向了一个内部函数地址
    inn()  # 在一个函数外部调用里面函数 延长了 a=1 的生存空间
    
    #>> (<cell at 0x000002AE11EA1888: int object at 0x00007FF9FC5CE350>,)  只要cell什么 证明就是闭包
    #>> None  不是闭包
    
    
    import urllib
    from urllib.request import urlopen
    
    
    def get_url():
        url = 'https://www.douban.com/'
        def get():
            ret = urlopen(url)
            print(ret)
        return get
    hai = get_url()
    hai()

     几道题

    1、写函数,检查获取传入列表或元祖对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者

    def func(l):
        return l[1::2] # 切片

    2.写函数 判断用户传入的值(字符串、列表、元祖)长度是否大于5

    def funlen(x):
        return len(x)>5

    3.写函数 检查传入列表的长度,如果大于2那边仅保留前两个长度的内容,并将新内容返回给调用者

    def lentwo(l):
        if len(l)>2:
            return l[:2]

    4.写函数 计算传入字符串中数字、字母、空格、以及、其他的个数,并返回结果

    def er(s):
        dic = {'num':0,'alpha':0,'space':0,'other':0}
        for i in s:
            if i.isdigit():
                dic['num']+=1
            elif i.isalpha():
                dic['alpha']+=1
            elif i.isspace():
                dic['space']+=1
            else:
                dic['other']+=1
        return dic
    print(er('jsdhfjs lksjdf654654 ds-0='))

    5.写函数,检查用户传入的对象(字符串、列表、元祖)的每一个元素是否含有空内容,并返回结果

    def ou(x):
        if type(x) is str and x:  # 参数是字符串
            for i in x:
                if i == ' ':
                    return True
        elif x and type(x) is list or type(x) is tuple:  # 参数是列表或者元祖
            for i in x:
                if not i:
                    return True
        elif not x:      # 直接就是空了
            return True
    print(ou(''))

    6.写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者

    die = {'k1':'vlvl','k2':[11,22,33,44]}  # 字典中的value只能是字符串或列表
    def di(dic):
        for k in dic:
            if len(dic[k])>2:
                dic[k] = dic[k][:2]
        return dic
    print(di(die))

    7.写函数,接受两个数字参数,返回比较大的那个数字

    def mymax(a,b):
        return a if a>b else b  # 三元运算
    print(mymax(3,3))
    #三运运算
    # 条件返回True的结果 if 条件 else 条件返回False的结果
    # 必须要有结果
    # 必须要有if和else
    # 只能是简单的情况

    8.写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整改文件的批量修改操作(进阶)(文件名要输入绝对路径)

    def file(filename,old,new):
        with open(filename,encoding='utf-8',) as f,
            open('%s.bak'%filename,'w',encoding='utf-8') as f1:
            for i in f:
                if old in i:
                    i = i.replace(old,new)
                f1.write(i)
        import os
        os.remove(filename)
        os.rename('%s.bak'%filename,filename)

    参考:http://www.cnblogs.com/Eva-J/articles/7125925.html

  • 相关阅读:
    Android查看应用方法数
    解决问题 inner element must either be a resource reference or empty.
    Android JSBridge原理与实现
    CDN详解
    Android studio 将 Module 打包成 Jar 包
    Imageloader、Glide、Fresco的性能及加载速度比较
    Mac之如何查看已用端口
    yum安装docker-ce-18.03.0
    脚本检测Kafka和Zookeeper
    Docker搭建ElasticSearch+Redis+Logstash+Filebeat日志分析系统
  • 原文地址:https://www.cnblogs.com/niunai/p/10524750.html
Copyright © 2020-2023  润新知