函数总结

函数定义与结构

  • 定义:函数就是一个功能,定义一个函数就是编写一个功能,调用一个函数就是实现一个功能。
  • 结构
    • 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. IBM WebSphere 远程代码执行漏洞安全预警通告

    近日,IBM发布安全通告称修复了一个WebSphere Application Server中一个潜在的远程代码执行漏洞(CVE-2018-1567).攻击者可以构造一个恶意的序列化对象,随后通过SO ...

  2. c++中set 的用法

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  3. yum报[Errno 256] No more mirrors to try

    解决方法: yum clean all            #清除yum缓存yum makecache      #将服务器软件包写到本地缓存,提高包的搜索.安装效率

  4. TEC-004-php文件下载任意文件读取漏洞修复

    修改download?u参数值,将/public/files/14842030529.txt,替换为../../../../../../../../../../etc/passwd    functi ...

  5. 常用的CSS小技巧

    实际开发过程中会遇到一些需要用CSS小技巧处理的布局问题,现在分享几个个人工作中遇到的小问题和解决方案. 1.inline元素间的空白间隙 这里要介绍一个神器font-size:0. 如果你写了个列表 ...

  6. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

    2019独角兽企业重金招聘Python工程师标准>>> 问题 前两天一个学弟在群里面问一个问题: 请问一下用阿里云服务器发送https请求为什么会失败,是需要有些其他什么配置吗? 同 ...

  7. 如何用Hexo搭建个人博客

    以前用Wordpress搭建过一个博客网站,Wordpress虽然安装简单,功能强大,但是对于个人建站来说有点复杂了.最近发现用Hexo建站很流行,于是将网站从Wordpress迁移到了Hexo. H ...

  8. UIResponder相关

    UIResponder是OC中一个响应事件的类.UIApplication.UIView.UIViewController都是它的子类.UIWindow是UIView的子类,因此也能响应事件. UIR ...

  9. Java——多线程之线程间通信

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...

  10. bootstrap 怎么制作好看的表格

    bootstrap 怎么制作表格 bootstrap 制作表格带有图文形式.主要知识点有以下几点 第一点肯定是写出一个普通的表格,这一点可以去菜鸟复制它的案例.添加tr和td就可以了 在表格放入图片加 ...