zoukankan      html  css  js  c++  java
  • 第八章 函数

     

           - 具有特定功能的代码块

           - 意义:①简化代码重复率

                         ②功能模块化

    一. 内置函数

           用法: 函数名[参数]

           返回: seq / None

           print, abs,

    二、自定义函数

    1. 语法格式

           def 函数名([参数]):

                  函数体

                  [pass 为占位符]

                  [return 返回值]

          

    2. 参数使用

           --- 函数的参数只在定义时创建一次,之后再次调用函数,不会给变量新创建内存

    (1) 位置参数(必须参数)

           --- 一旦定义,除默认参数必须按照顺序传入,位置固定

           > 位置参数必须放在最前面

          

    (2) 默认参数

           --- 给参数赋予默认值,如果不传入,使用默认值

           > 默认形式参数不要使用可变类型,否则重复调时,默认值会被修改

          

    (3) 命名关键字参数 - *,

           def 函数名(*, 参数名, 参数名...):

                  #'*,',关键字参数和命名关键字参数的传参,必须通过【参数名= 参数值】形式传入

           > 调用

                  ①只能【参数名= 参数值】形式传入

                  ②顺序不需要固定

           > 优点

                  ① 增加程序可读性

                  ② 忽略参数的作用

                  ③ 当参数有默认值时,等同于默认参数

                  ④ 除了指定默认值,必须传入参数

    (4) 可变参数 - * args

           --- 用来收集所用的位置参数,打包成一个元组

           def 函数名(* args):

           > args 为元组,因为可变参数函数定义时,可以把零散位置参数打包成元组

           > 对于元组或者列表(args或者自定义传入值),应该使用“*”解包

     

    (5) 关键字参数 - ** kwargs

           --- 把命名关键字打包成字典

           def 函数名(** kwargs):

     

    (6) 万能参数

                  * arg, ** kwargs

    注意:

           (1) 位置参数必须在最前面

           (2) 命名关键字参数不能和可变参数放在一起

           (3) 优先顺序:

                  位置参数 > 默认参数 > 命名关键字参数 / 可变参数 > 关键字参数

          

           def fu1(a,b,c=0,*args, **kwargs):

           >>> 前三个参数被赋值给abc,多余葡萄普通参数传入args,输入关键字参数,传入kwargs

           def fu2(a,b,c=0,*,d, **kwargs):

           如果有d,关键字参数优先传入d,其他关键字优先传入kwargs

          

    3. 返回值

           > return语句的执行,代表函数的结束

           > 返回值只能有一个,如果需要多个值,可以以元组返回;

           > 以下返回值为None

           (1) return

           (2) reutrn None

           (3) 不写

           > 函数最好传入和返回值都使用元组等不可变类型

          

    4. 函数中的值传递

           > 不可变类型的值传递

                  --- 形参指向传入的实参对象,修改创建新对象,两者互不影响

           > 可变类型的值传递

                  --- 形参指向传入的实参对象,直接修改对象,函数对实参发生影响

     

    5. 命名空间和作用域

    <1> 命名空间

         (1) 概念

           命名空间 : 可以保存名字的容器

                                > 包括:变量名、函数名、类名

                                > 命名空间中,名字以key-value字典结构存储,其中key为变量名,value为内存地址

                                > 每一种命名空间都有固定区域

           对于函数:

                  第一次def时,构建命名空间

           对于变量:

                  第一次赋值时,构建命名空间

         (2) 分类

           ① 内建命名空间

                  --- python解释器启动的时候创建,解释器关闭时销毁

                         如: sum, print

           ② 全局命名空间

                  --- 读取模块定义的时候创建,程序运行结束,空间销毁

                         如: 全局变量,顶层函数

           ③ 局部命名空间

                  --- 在函数创建时创建,函数执行结束时销毁

                         如: 局部变量,形式参数, 嵌套函数

           注意: 命名空间不存在包含关系,只存在生命周期,或者说作用域不同。

          

           > 各命名空间创建顺序:

             python解释器启动 ->创建内建命名空间 -> 加载模块 -> 创建全局命名空间 ->函数被调用 ->创建局部命名空间

           > 各命名空间销毁顺序:

             函数调用结束 -> 销毁函数对应的局部命名空间 -> python虚拟机(解释器)退出 ->销毁全局命名空间 ->销毁内建命名空间

          

    <2> 作用域

           --- 命名空间中的名字起作用的范围

                  ① 内建命名空间 --- 整个运行环境所有模块

                  ② 全局命名空间 --- 仅限当前py文件,使用其他py文件需导入

                  ③ 局部命名空间 --- 仅限函数内部有效

           注意: 作用域不存在包含关系,只是大小不同;

                     文件名,变量名,函数名...不要用内建命名空间变量名

          

    <3> 访问原则

         (1) LEGB原则

                  > 作用域按照变量的定义位置可以划分为4类:.

                  Local     (函数内部)               局部作用域

                  Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)

                  Global   (模块全局)              全局作用域

                  Built-in (内建)                  内建作用域

         (2) 名称的访问

                  > 读取 --- LEGB

                  > 修改 --- 只从当前最小作用域查找,如果找到修改,找不到创建

                                   globla, nonlocal方法可以修改

                  > 删除 --- 只能删除当前命名空间名字

         (3) global nonlocal

                  global   --- 局部命名空间修改全局命名空间内容

                  nonlocal --- 局部命名空间修改外围命名空间内容

         (4) 显示命名空间

                  local()   --- 可以显示该语句所在位置的命名空间

                  global() --- 显示全局命名空间

                         

    
    	eg.
    	def f():
    		k = 'asdf'
    		def inner():
    			nonlocal k
    			k = 'qewr'
    			# del k 报错,无法删除上一级命名空间
    		inner()
    		print(k)
    

     

    6. lambda表达式(匿名函数)

           > 头等函数: 变量和函数类型、函数名可以被赋值、传递、和作为返回值

         

         #函数名赋值
    	def hello():
    		print('hello')
    	hello_new = hello
    	hello_new()
    
    	# 函数名当成返回值
    	def outer():
    		def inner():
    			print('dsaf')
    		return inner
    	a = outer()
    	a()
    
    	# 函数名当成值被传递
    	def hello():
    		print('hello')
    	def k(m):
    		pass
    	k(hello)

       

    (1) 定义

           lambda参数: 返回值表达式

    (2) 使用场景

           函数体比较简单

    from numpy import square
    li = [1, 2, 4]
    li.sort(key = lambda x: x**2)
    li.sort(key = square)

    7. 递归

           --- 函数调用自身

           (1) 直接递归

           (2) 间接递归

           递归一定要通过条件终止,分为递推回归两个步骤

           > 递归和循环

                  1. 递归思路简单,但是效率比循环低

                  2. 递归有最大深度(所有函数调用次数),default = 1000

                      最大递归次数通过sys.getrecursionlinit()获取

         

    	# 斐波那契数列
    	def fb(n):
    		if n ==1 or n ==2:
    			return 1
    		else:
    			return fb(n-1)+fb(n-2)

           # for斐波那契数列

           # 多维列表解包

           # 汉诺塔 - 列表

                 

    8. 函数注释(文档)

           --- 在函数下用三引号

           显示:

                  > print(函数名.__doc)

                  > help(函数名)

                 

           --- 参数形式的标注

                  def add(a: int, b:float)->int:

                  print(函数名.__annotation__)

          

                 

          

          

  • 相关阅读:
    Mac下ssh连接远程服务器时自动断开问题
    解决php中json_decode的异常JSON_ERROR_CTRL_CHAR (json_last_error = 3)
    如何写.gitignore只包含指定的文件扩展名
    python操作mysql数据库
    php数组函数
    Python中字符串切片操作
    Python实现字符串反转的几种方法
    每个Android开发者都应该了解的资源列表
    Android Studio 入门指南
    一个优秀的Android应用从建项目开始
  • 原文地址:https://www.cnblogs.com/geoffreyone/p/9899766.html
Copyright © 2011-2022 走看看