day09&day10 课程记录 (初识函数&函数进阶)

函数基础部分

.什么是函数?

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。

2.定义函数

定义:def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。
   def 是固定的,不能变,他就是定义函数的关键字。
   空格:为了将def关键字和函数名分开,必须空(四声),当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格。
   函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并能表达函数功能(变量的命名规范)
   括号:是必须加的,先别问为啥要有括号,总之加上括号就对了!
    注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
     调用:就是 函数名() 要记得加上括号。

3.函数调用和参数

函数要先定义,后执行。定义完了之后不调用,就不执行
def userinfo(name,age,sex=""):  #其中sex是默认参数,name,age是未知参数
    info = "姓名是%s,年龄是%s,性别是%s"%(name,age,sex)
    return info
user=userinfo('kobe',age=18,sex="") #其中kobe是未位置参数,age,sex是关键字参数
print(user)

函数名():不管是在哪个地方出现都是在调用函数

函数的参数:
    形参--->函数定义的时候
            位置参数  a,b 传参的时候一一对应从实参处接受
            默认参数  a=1 在定义的时候就设定好值了

    实参--->函数调用的时候
            位置参数  1,2, 传参的时候一一对应给形参
            关键字参数 a=1 通过形参的名字指定传值
    混合:
            形参 def func(a,b,d,f=1):
            实参 func(1,2,3,f=2)

    传参--->将实参传递给形参的过程

  #形式参数-->变量名后面()里面的参数
  #实际参数-->实际上要传递的参数
  #传参-->将实参传递给形参的过程叫做传参,
  #位置参数-->形参和实参是有一个位置的关系,能一一对应,叫做位置参数
  #默认参数-->定义默认参数的时候,有时候传递的实参和接受的形参数量并不一定相等
  #关键字参数-->这样就不需要记住每一个参数的位置了,只需要在调用的函数的时候,给参数进行赋值就可以
  注意:位置参数优先级要高于关键字参数(如果位置参数传递不正确的话会报错)

4.函数的返回值

1.没有return就默认返回None
2.写了return 没有写返回值 默认返回None
3.多个返回值的时候,返回的是一个元组
4.一个返回值的时候,返回的就是返回值本身
5.return 下面的代码不执行,并且结束这个函数

返回值作用:
  1,结束整个函数。return下面的代码都不执行
  2,给函数的执行者(调用者)返回值。

返回值返回给谁:
  谁调用函数就把返回值返回给谁

5.初识函数其他知识点

1.函数先定义后执行,定义完了之后不调用,就不执行
2.print(函数名) --->函数的内存地址---><function userinfo at 0x0000000001D31E18>
3.函数执行过程:定义--->调用---->函数体代码
4.谁调用了函数,函数的返回值就返回给谁。如果返回值是1个,就返回字符串,2个以上的话,就返回元组
5.函数名():不管在哪个地方都是在调用函数
6.传递参数时:位置参数要高于关键字参数,一定要将位置参数--对应之后,只进行关键字赋值
7.三元运算符:c = a if a>b else b--->如果a>b就将a的值返回给c,否则就将b的值返回给c (通常在不确定到底是什么数值的时候用到)

other 

1.全局变量必须要定格去定义,不能定义在缩进里面
2.()叫做调用操作符,[]叫做索引操作符
3.如果直接要是用一个便令,默认使用全局的

函数进阶部分

1.动态参数

*agrs:接受的位置参数,返回元组
**kwargs:接受关键字参数,返回字典

动态参数:
  动态参数的用途:在不明确接受参数的数量时,使用*args和**kwargs来接受参数,分别返回
  注意:*args和**kwargs中的英文字母可以是任意的符合变量定义规范的数据类型,但是通常不这么做!
动态参数出现位置:
  动态位置参数>动态关键字(默认)参数
  形参:位置参数>动态位置参数>默认参数>动态关键字(默认)参数
  实参:位置参数>关键字参数
动态参数中*的作用:
  实参:
    *args在实参处调用时,*将可迭代对象打散,字典是将键值取出
    **kwargs在实参处调用时,将字典打散,形成关键字参数,{键:值}相互对应
  形参:
    *args在形参处出现时,*代表的是将接收到的位置参数聚合成元组
    **kwargs在形参处出现时,**代表的是将接收到的关键字参数聚合成字典
复制代码

 2.函数注释

def info(user,name):
    """
    :param user:
    :param name:
    :return:
    """
    print(1)
#在函数体内,连续输入三个双引号的因为字符,然后回车
查看注释: func名.__doc__
查看文件名: func名.__name__
查看文件路径:
  import os
  print(os.path.abspath(__file__))

3.命名空间:把同名的变量区分出不同的作用域

在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来。
但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了,  至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此而已!
只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空. 

我们给存放名字和值的关系的空间起一个名字叫: 命名空间. 我们的变量在存储的时候就 是存储在这片空间中的.   
命名空间的分类:
  内置空间: 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间
  全局空间: 我们直接在py文件中, 函数外声明的变量都属于全局命名空间
  内置空间: 在函数中声明的变量会放在局部命名空间
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值顺序:找不到就报错
  在局部调用:局部命名空间->全局命名空间->内置命名空间
  在全局调用:全局命名空间->内置命名空间

作用域:作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
  全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
  局部作用域:局部名称空间,只能在局部范围内生效,函数内部生效

global:在局部修改全部变量,如果没有就创建一个新的。
  nonlocal:在局部空间内,修改离自己最近的变量,如果上一层没有就继续向上找,直到找到局部变量的顶层,局部空间内没有可以修改的变量,就报错。

 4.函数嵌套

1. 只要遇见了()就是函数的调用. 如果没有()就不是函数的调用
2. 如果看见了print(函数名)是打印函数的内存地址
global:
global:
  1,声明一个全局变量。
  2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)。
  ps:对可变数据类型(list,dict,set)可以直接引用不用通过global。
代码示例:
  a = 100
  def func():   
      global a    # 加了个global表示不再局部创建这个变量了. 而是直接使用全局的a   
      a = 28   
  print(a)
  func()
  print(a)

 nonlocal

nonlocal:
  1,不能修改全局变量。
  2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
代码示例:
    a = 10
    def func1():   
        a = 20   
        def func2():
            nonlocal a       
            a = 30       
            print(a)  
        func2()   
        print(a)
    func1()
     
    结果:
    加了nonlocal
    30
    30
     
    加nonlocal
    30
    20   

函数的作用域链:小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。

 other

函数名本质上就是函数的内存地址或对象。
    1.可以被引用
    2.可以被当作容器类型的元素
    3.可以当作函数的参数和返回值
    4.如果记不住的话,那就记住一句话,就当普通变量用

闭包函数:内部函数包含对外部作用域而非全局作用域变量的引用,该内部函数称为闭包函数
闭包函数的常用实践:
  由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!
  我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?
  是不是直接就把这个函数的名字返回就好了?
  这才是闭包函数最常用的用法

代码实现:
  def func():
     name = 'eva'
     def inner():
         print(name)
      #print(inner.__closure__)有cell元素,就是闭包元素
     return inner  #返回的时inner的内存地址
  f = func()
   f()

猜你喜欢

转载自www.cnblogs.com/jiazeng/p/10543367.html
今日推荐