函数总结

函数定义与结构

  • 定义:函数就是一个功能,定义一个函数就是编写一个功能,调用一个函数就是实现一个功能。
  • 结构
    • def 函数名(形参):
    • 结构体:缩进,在结构体中尽量少使用print( ),这样为了提高效率
    • return:给函数的执行者返回参数
      • 没有return:返回None给执行者
      • return单值:返回该值给执行者
      • return多值:返回一个元组给执行者

函数名的使用

  • 函数名+( )就可以执行函数

  • 函数名其实就是一个变量

    def func():
    print('hello')
    f=func
    f1=f
    f()
    f1()
  • 函数名可以作为容器类数据结构的元素

    def func1():
    print('from fun1')
    def func2():
    print('from fun2')
    f=[func1,func2]
    for i in f:
    i()
  • 函数名可以作为参数传递

    def func1(f):
    print('from fun1')
    f()
    def func2():
    print('from fun2')
    func1(func2)
  • 函数名可以作为return返回

    def func1(f):
    print('from fun1')
    return f
    def func2():
    print('from fun2')
    ret=func1(func2)
    ret()

函数的参数

  • 函数在定义调用过程中有两种参数,一种时定义时的形参,另一种是调用时的实参

  • 实参包括

    • 位置参数:如1,'hello',位置参数一定要在关键字参数前面
    • 关键字参数:如name='yzh'
    • 混合参数:既包含位置参数又包含关键字参数
  • 形参包括

    • 位置参数:对应实参的位置参数,如a,b
    • *args参数
    万能参数*args:其中*在函数定义时代表了聚合,会将除实参对应的形参位置参数外的所有位置参数都集合成一个元组,将元组传递给args
    • 默认参数:对应与实参的关键字参数,如实参没传参数给默认参数,则使用自己的默认值,若传了参数,则用实参传递的参数,如name='大白'
    • 仅限关键字参数(了解):对应于实参的关键字参数,且实参关键字的变量名必须于关键字的名字一样。
    • **kwargs)参数
    万能参数**kwargs:其中**在函数定义时代表了聚合,会将除实参对应的形参位置参数外的所有位置参数都集合成一个字典,将字典传递给kwargs

    函数实参的排序(位置参数,关键字参数)

    形参的排序(位置参数,*args,默认参数/仅限关键字参数,**kwargs)

    #func(位置参数,关键字参数)
    func(1,2,'hello','world',name='yzh',age=18,height=18,c='yzh')
    #def func(位置参数,*args,默认参数/仅限关键字参数,**kwargs)
    def func(a,b,*args,name='大白',c,**kwargs)
  • *和**在函数调用时的魔性用法(在调用时代表了打散)

    def func(*args,**kwargs):
    print(args,kwargs) #(1, 2, 3, 'name', 'age') {'name': '大白', 'age': 18}
    func(*[1,2,3],*{'name':'大白','age':18},**{'name':'大白','age':18}) # *会将列表中的数据一一打散,而对于字典则只会取出字典的键

名称空间与作用域

名称空间

  • 名称空间包含全局名称空间,局部名称空间,内置名称空间

    • 全局名称空间:当前执行的.py文件
    • 内置名称空间:builtins.py
    • 局部名称空间:函数被调用时开启,函数被调用时关闭
  • 名称空间加载顺序
    • 内置名称空间—>全局名称空间—>局部名称空间
  • 名称空间取值顺序(就近原则,单向不可逆,LEGB原则)
    • (从局部开始时):局部名称空间—>全局名称空间—>内置名称空间

作用域

  • 作用域分为全局作用域和局部作用域

    • 全局作用域:全局名称空间+内置名称空间
    • 局部作用域:局部名称空间
    #注意:局部作用域不能修改全局作用域的值,当python解释器在局部作用域读取到你对一个变量进行修改操作,解释器会认为你在修改前就在局部作用域内定于了该变量,它就会从局部取寻找这个变量,没有找到就报错(一定先定义在使用)

函数嵌套

内置函数(globals( ),locals( ))

  • globals( ):返回一个字典,字典中键值对是全局作用域的所有内容

  • locals( ):返回一个字典,字典中键值对是当前作用域的所有内容

    def func(*args,**kwargs):
    print(args,kwargs)
    print(locals())
    func(*[1,2,3],**{'name':'yzh','age':18})
    print(locals())
    print(globals())

global+nonlocal

  • global:在局部作用域中声明一个全局变量,使得可以该局部作用域中对声明的全局变量进行修改

    a=10            #定义一个全局变量a
    def func():
    global a #在局部作用域中global声明一个全局变量a
    a-=10 #可以对a进行修改操作
    return a
    print(func())
  • nonlocal:一般在嵌套函数中,主要用于内层函数对外层函数局部变量的修改,但不能修改全局变量

    • 注意:不能先global一个全局变量,然后在嵌套内置函数中再nonlocal一次该变量
    a=10                #定义一个全局变量a
    def func():
    a=5 #在局部作用域中声明一个全局变量a
    def inner(): #在func中再定义一个内层函数inner,构成嵌套函数
    nonlocal a
    a-=4 #可以对局部作用域中的a进行修改操作,不能对全局变量a进行修改
    print(a)
    return a
    return inner()
    print(func())

可迭代对象和迭代器

可迭代对象

  • 可迭代对象定义:内部含有__ iter __方法的对象,比如:str,list,tuple,set,dict,range

  • 判断对象是否为可迭代对象的方法:dir(x),x为对象

    print('__iter__' in dir(x)) #True的话说明x就是可迭代对象
  • 可迭代对象的特点

    • 优点

      • 存储的数据可以直接输出,比较直观
      • 操作方法多
    • 缺点
      • 当数据较多时,会占用内存
      • 不能直接取值(索引和key除外),必须啊通过for进行一一取值

迭代器

  • 迭代器的定义:内部含有' __ iter __ ' 以及 ' __ next __ '方法的对象,比如文件句柄

  • 判断对象是否为迭代器的方法:dir(x),x为对象

    print('__iter__' in dir(x) and '__next__' in dir(x))   #True的话说明x就是迭代器
  • 迭代器的特点

    • 优点

      • 节省内存(读完一条,消失,再读一条)
      • 惰性机制(next一次就取一次值)
    • 缺点
      • 以时间换空间(执行效率慢)
      • 不能回去取值,只能往下取值

总结

  • 迭代器一定是可迭代对象,可迭代对象不一定是迭代器

  • 将迭代对象转化为迭代器的方法:iter(x),x为可迭代对象

    ls=[1,2,3,4]
    ls_iter=iter(ls) #通过iter()的方法将可迭代对象ls转化为迭代器
    while True:
    try:
    for i in range(10):
    print(next(ls_iter)) #通过next()的方法将迭代器中的值一一取出
    except StopIteration:
    break
  • 可迭代对象与迭代器的对比

    • 可迭代对象用于许多的操作方法,可对对象进行灵活操作,而且存储的数据清晰明了,所以当你的内存空间足够大且需要灵活操作数据时可以选择将数据存储为可迭代对象
    • 但是当数据过多,大到足以撑爆内存时,我们就需要以节省内存为第一考虑点,这时将数据存储为迭代器比较合适
  • 利用while循环模拟for循环的迭代器取值

    ls=[1,2,3,4]
    ls_iter=iter(ls)
    while True:
    try:
    print(next(ls_iter))
    except StopIteration:
    break

解析语法与生成器

解析语法

列表解析式
  • 定义:用一行代码构建的比较复杂且有规律的列表

  • 模式:一类是循环模式,一种是筛选模式

    #循环模式 [i for i in iterable可迭代对象]
    ls=[i for i in range(10)]
    #筛选模式 [i for i in iterable可迭代对象 if ......]
    ls=[i for i in range(10) if i>3]
  • 特点

    • 优点

      • 简单方便,一行搞定
    • 缺点
      • 只能构建比较复杂且必须有规律的列表
      • 如果循环次数超过了三层不建议使用列表解析式
      • 一旦出错,不好找错误
其他解析式
  • 字典解析式

    dic={i:i**2 for i in range(5)}
  • 集合解析式

    se={i for i in range(5)}

生成器

  • 定义:在python社区中,生成器与迭代器式是一样的,生成器的本质就是迭代器,唯一的区别在于生成器是我们通过pyhon代码构建的数据结构,迭代器是python提供或转化来的

  • 获得生成器的途径(三种,生成器函数,生成器表达式,某些内置函数)

    • 生成器函数

      • 只要函数中有yield或yield from,这是函数就是生成器函数,不再是普通的函数了

      • return 与yield的对比

        • return:函数中只能拥有一个return,return意味着函数结束,同时将值返回给函数执行者
        • yield:一个生成器函数中可以有多个yield,yield结束不代表生成器函数结束,同时一个yield对应一个next
        #yield
        def func():
        ls=[1,2,3]
        yield ls
        ret=func()
        print(next(ret)) #[1, 2, 3] #yield:将可迭代对象的元素一一拆开
        def func():
        ls=[1,2,3]
        yield from ls
        ret=func()
        print(next(ret)) #1
        • send(了解)
        def per(name):
        print(f'{name} ready to eat')
        while 1:
        food = yield
        print(f'{name} start to eat {food}')
        dog = per('大黄')
        next(dog) # 第一次必须用next让指针停留在第一个yield后面
        # 还可以给上一个yield发送值
        dog.send('骨头')
        dog.send('狗粮')
        dog.send('香肠')
      • send和next()区别:

        • 相同点:

          • send 和 next()都可以让生成器对应的yield向下执行一次
          • 都可以获取到yield生成的值
        • 不同点:
          • 第一次获取yield值只能用next不能用send(可以用send(None)
          • send可以给上一个yield置传递值
    • 生成器表达式

      • 生成器表达式与列表解析式很相似,唯一的区别在于,列表解析式是[],而生成器表达式是( )
      • 通过next,list(),(for i in 生成器表达式)的方式去取值
      l=(i,for i in range(10))
      #三种取值方式
      1.print(list(l))
      2.print(next(l))
      3.for i in l:print(i)
    • 一些内置的函数(filter( ), map( ) ,zip( ) reversed( )等)

闭包和装饰器

闭包

  • 定义:在嵌套函数中,内层函数对外层非全局变量的引用或使用,其中该非全局变量为自由变量

    • 自由变量是介于全局变量和局部变量之间的一种特殊变量,它会与内层函数形成一个绑定关系,且会在全局作用域中形成一个独特的空间来单独存放自由变量

  • 作用:保证数据的安全

  • 怎么判断闭包:使用(函数名.__ code __. co _freevars),会以元组的形式返回自由变量

    #第一种,内层函数对外层非全局不可变类型变量进行引用操作
    def func(a,b):
    def inner():
    print(a,b)
    return inner
    ret=func(1,2)
    print(ret.__code__.co_freevars) #('a','b')
    #第二种,内层函数对外层非全局不可变类型变量进行修改操作
    def func():
    a=10
    def inner():
    nonlocal a #记得加上nonlocal
    a-=5
    print(a)
    return inner
    ret=func()
    print(ret.__code__.co_freevars) #('a',)
    #第三种,内层函数对外层非全局可变类型变量进行修改或引用操作
    def func():
    ls=[]
    def inner():
    ls.append(1)
    print(ls)
    return inner
    ret=func()
    print(ret.__code__.co_freevars)

装饰器

  • 定义:装饰器的本质就是闭包,完全遵循开放封闭原则,在不改变函数的源码以及调用方法的情况下为函数增加新的功能

    • 开放封闭原则:对函数的功能拓展是开放的,对函数的源码是封闭的
  • 使用途径:进入页面的登录认证等

  • 装饰器的标准代码

    def wrapper(f):
    def inner(*args,**kwargs):
    #执行被装饰函数前添加的新功能
    ret=f(*args,**kwargs)
    # 执行被装饰函数后添加的新功能
    return ret
    return inner
    @wrapper #等同于func=wrapper(func)
    def func():
    return 666

lambda函数+内置函数

lambda函数

  • lambda函数也叫匿名函数,一句话函数,所谓匿名,就是与关键字def函数相比,没有函数名称,lambda函数多与内置函数,列表推导式相结合

    • lambda[参数]:表达式:表达式也是lambda函数的返回值
  • 特点

    • lambda后没有函数名,但是可以将整个lambda函数传给一个变量名,这个变量名也就成了新的函数名
    fun=lambda x:x**2
    print(fun(2))
    • 整个函数在一行内实现所有定义,简单方便,有效减少冗余代码

内置函数

  • python包含了68个内置函数

    • 了解:eval() exec() hash() help() callable() int() float() complex() bin() oct() hex() chr() ord() round() divmod() pow() all() any() bytes() repr() format() frozenset() globals() locals() id() input() print() str() list() tuple() iter() next() dict() set() sum() range() abs() enumerate() type() dir() reversed() zip()

    • 重点:带key的,内置函数中凡是带key的,它都自动的将可迭代对象的元素按照顺序传入key对应的函数中

      • max(*args,key=None)
      • min(*args,key=None)
      ls=[-1,2,3,-7]
      print(max(ls,key=lambda x:abs(x)))
      print(min(ls,key=lambda x:abs(x)))
      • sorted(*args,key=None,reverse=True/False):reverse=True表示从大到小,False表示从小到大,不会改变原迭代对象的顺序
      ls=[[1,2],[4,5],[9,3]]
      print(sorted(ls,key=lambda x:x[1],reverse=True))
      • filter(key,*args):返回的是一个生成器
      ls=[1,2,4,3,7,5,9]
      i=filter(lambda x:x>3,ls)
      print(list(i))
      • map(key,*args):返回的是一个生成器,与列表推导式相似,但前者返回的是生成器,后者返回列表
      ls=[1,2,4,3]
      i=map(lambda x:x**2,ls)
      print(list(i))
      • reduce(key,*args):reduce必须从functools模块中导入
      from functools import reduce
      def func(x,y):
      return x+y
      ls=[1,2,3,4]
      print(reduce(func,ls))
      #第一次:x=1,y=2 获取结果x+y=3,将3作为下一个x的参数
      #第二次:x=3,y=3 获取结果x+y=6,将6作为下一个x的参数
      #第三次:x=6,y=4 获取结果x+y=10,将10作为最终的结果返回reduce()
    • 后面会谈及:classmethod() delattr() getattr() hasattr() issubclass() isinstance() object() property() setattr() staticmethod() super()

python函数总结,你值得拥有的更多相关文章

  1. python 函数之day3

    一 函数的语法及特性 什么是函数? 定义:函数是一个功能通过一组语句的集合,由名字(函数名)将其封装起来的代码块,要想执行这个函数,只要调用其函数名即可. 特性: 减少重复代码 使程序变的可扩展 使程 ...

  2. Python函数作用域的查找顺序

    函数作用域的LEGB顺序 1.什么是LEGB? L:local 函数内部作用域 E:enclosing 函数内部与内嵌函数之间 G:global 全局作用域 B:build-in 内置作用域 2.它们 ...

  3. Python函数讲解

    Python函数

  4. Python函数信息

    Python函数func的信息可以通过func.func_*和func.func_code来获取 一.先看看它们的应用吧: 1.获取原函数名称: 1 >>> def yes():pa ...

  5. Python函数参数默认值的陷阱和原理深究"

    本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...

  6. Python开发【第四章】:Python函数剖析

    一.Python函数剖析 1.函数的调用顺序 #!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #函数错误的调用方式 def fun ...

  7. Python函数解析

    对于Python的函数,我们需要记住的是: 1. 函数的默认返回值是None. 2. python是一个自上而下逐行解释并执行的语言.因此,函数的定义必须在函数被调用之前.同名的函数,后定义的会覆盖前 ...

  8. Python入门笔记(18):Python函数(1):基础部分

    一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...

  9. Python函数1

    Python 函数命令的使用 想想我们之前数学中学到的函数,首先我们需要定义一个函数,例如f(x)=x, 当x输入任意数的时候,f(x)都能输出和x相等的数值. 那么在Python中是如何实现的呢? ...

  10. python函数传参是传值还是传引用?

    首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...

随机推荐

  1. Phaser都不懂,还学什么多线程

    前面的文章中我们讲到了CyclicBarrier.CountDownLatch的使用,这里再回顾一下CountDownLatch主要用在一个线程等待多个线程执行完毕的情况,而CyclicBarrier ...

  2. C++操作Kafka使用Protobuf进行跨语言数据交互

    C++操作Kafka使用Protobuf进行跨语言数据交互 Kafka 是一种分布式的,基于发布 / 订阅的消息系统.主要设计目标如下: 以时间复杂度为 O(1) 的方式提供消息持久化能力,即使对 T ...

  3. CentOS7虚拟机安装vmtools

    直接开始: 在安装vmtools之前,需要先安装两个小部件,否则将安装失败. 下面是步骤: 1.切换为root模式,需要输入root密码,但是不显示. 命令为: su 2.安装gcc 命令为: yum ...

  4. 【JAVA基础】04 Java语言基础:方法

    1. 方法概述和格式说明 为什么要有方法 提高代码的复用性 什么是方法 完成特定功能的代码块. 方法的格式 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...) {     方法 ...

  5. Vue-cli3.0下的雪碧图插件webpack-spritesmith配置方法

    在前端项目中,为了减少对图片的请求次数,一般而言需要进行雪碧图的配置.即将多张小图标合并成一张图片,这样页面中的小图标都在一张图片上,只需请求一张图片,就可以通过CSS设置各个小图标的显示,利于节省带 ...

  6. Firefox 66 发布,阻止网站自动播放声音

    Firefox 66 发布了,此版本在桌面版中带来的新特性包括: Firefox 现在阻止网站自动播放声音,如果需要可以单独调整 改进的搜索体验: 当打开许多选项卡时,可以更快地查找特定网页:现在可以 ...

  7. 替换input单选框的样式

    实现效果:. css的input单选框的样式很丑,有时候不想使用原生的样式,如上照片,可以使用下面的方法. 思路是,给inpu加visibility:hidden隐藏,然后使用不同的图片绝对定位覆盖在 ...

  8. NetCore项目实战篇02---全局异常处理

    在 .netcore中可以自定义自己的异常类型,步骤如下: 1.自定义自己的异常类型UserOperationException 并继承自Exception public class UserOper ...

  9. Codeforce 1098-A

    A. Sum in the tree   Mitya has a rooted tree with nn vertices indexed from 11 to nn, where the root ...

  10. P3831 [SHOI2012]回家的路

    P3831 [SHOI2012]回家的路 分层图基础题,就是建图稍有麻烦   #include<cstdio> #include<algorithm> #include< ...