Python6 - 函数总结
一、函数的基本知识
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
- 减少重复代码
- 使程序变的可扩展
- 使程序变得易维护
1.1函数定义规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
1.2语法格式:
- def 函数名(参数列表):
- 函数体
1.3函数的参数:
- 默认参数
- 位置参数
- 关键参数
- 非固定参数 *args 和 **kwargs
默认参数:
调用函数时,如果没有传递参数,则会使用默认参数。
- #可写函数说明
- def printinfo( name, age = 35 ):
- "打印任何传入的字符串"
- print ("名字: ", name);
- print ("年龄: ", age);
- return;
- #调用printinfo函数
- printinfo( age=50, name="runoob" );
- print ("------------------------")
- printinfo( name="runoob" );
默认参数实例
位置参数:
注意: 位置参数的顺序不可变。
关键字参数:
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
- def printme( str ):
- "打印任何传入的字符串"
- print (str);
- return;
- #调用printme函数
- printme( str = "菜鸟教程");
关键字参数实例1
关键字参数的使用不需要指定顺序
- #可写函数说明
- def printinfo( name, age ):
- "打印任何传入的字符串"
- print ("名字: ", name);
- print ("年龄: ", age);
- return;
- #调用printinfo函数
- printinfo( age=50, name="runoob" );
关键字参数实例2
非固定参数:
非固定参数或者不定长参数,上述3种参数不同,声明时不会命名,基本语法:
- def functionname([formal_args,] *var_args_tuple ):
- "函数_文档字符串"
- function_suite
- return [expression]
加了星号(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。
- # 可写函数说明
- def printinfo( arg1, *vartuple ):
- "打印任何传入的参数"
- print ("输出: ")
- print (arg1)
- for var in vartuple:
- print (var)
- return;
- # 调用printinfo 函数
- printinfo( 10 );
- printinfo( 70, 60, 50 );
不定长参数实例
需要注意:
- 关键参数必须放在位置参数之后。
- *args 会把多传入的位置参数变成一个元组(tuple)形式
- *kwargs 会把多传入的关键参数变成一个字典dict形式
1.4全局与局部变量:
- 对于数字和字符串来说在函数内部默认是不能更改全局变量的
- 如果非要在函数内硬改全局变量,需要在函数内添加 global 函数名,具体见下面global实例1
- 但是这种做法并不推荐
- myname = "Rong"
- def change_name():
- global myname #不推荐,不要用
- myname = "TanRong"
- change_name()
- print(myname)
global实例1
- names_list = ["Jack","Tom","xiaohong"]
- info_dict = {"name": "Jack", "age":18, "sex":"女"}
- def change_name():
- # global myname
- # myname = "TanRong"
- names_list[0] = "xiaoming"
- info_dict["age"] = 20
- change_name()
- # print(myname)
- print(names_list)
- print(info_dict)
- 输出:
- ['xiaoming', 'Tom', 'xiaohong']
- {'name': 'Jack', 'age': 20, 'sex': '女'}
实例2
1.5返回值:
- 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
- 如果未在函数中指定return,那这个函数的返回值为None
二、特殊函数
2.1递归函数:
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
- def calc(n):
- print(n)
- if int(n/2) ==0:
- return n
- return calc(int(n/2))
- calc(10)
- 输出:
- 10
- 5
- 2
- 1
Python实例
递归特性:
1. 必须有一个明确的结束条件,, 默认深度好像是999
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
- data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
- def binary_search(dataset,find_num):
- print(dataset)
- if len(dataset) >1:
- mid = int(len(dataset)/2)
- if dataset[mid] == find_num: #find it
- print("找到数字",dataset[mid])
- elif dataset[mid] > find_num :# 找的数在mid左面
- print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
- return binary_search(dataset[0:mid], find_num)
- else:# 找的数在mid右面
- print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
- return binary_search(dataset[mid+1:],find_num)
- else:
- if dataset[0] == find_num: #find it
- print("找到数字啦",dataset[0])
- else:
- print("没的分了,要找的数字[%s]不在列表里" % find_num)
- binary_search(data,66)
递归函数实际应用案例,二分查找
2.2嵌套函数:
顾名思义,函数内定义并调用函数
- name = "Tan"
- def change_name():
- name = "Tan2"
- def change_name2():
- name = "Tan3"
- print("第3层打印", name)
- change_name2() # 调用内层函数
- print("第2层打印", name)
- change_name()
- print("最外层打印", name)
嵌套函数实例
修改嵌套作用域:
要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了
- def outer():
- myage = 118
- def inner():
- nonlocal myage # nonlocal关键字声明
- myage = 126
- print(myage)
- inner()
- print(myage)
- outer()
- 输出:
- 126
- 126
nonlocal实例
2.3匿名函数:
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法如下:
- lambda [arg1 [,arg2,.....argn]]:expression
- sum = lambda a,b: a + b
- print(sum(30,50))
匿名函数实例1
- res = map(lambda x:x**2, [1,2,3,4,5])
- for i in res:
- print(i)
- 输出:
- 1
- 4
- 9
- 16
- 25
匿名函数实例2
2.4高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
- def add(x,y,f):
- return f(x) + f(y)
- res = add(3,-6,abs)
- print(res)
高阶函数实例
2.5内置函数
详解:https://docs.python.org/3/library/functions.html?highlight=built#ascii
- #compile
- f = open("函数递归.py")
- data =compile(f.read(),'','exec')
- exec(data)
- msg = "又回到最初的起点"
- f = open("tofile","w")
- print(msg,"记忆中你青涩的脸",sep="|",end="",file=f)
- # #slice
- # a = range(20)
- # pattern = slice(3,8,2)
- # for i in a[pattern]: #等于a[3:8:2]
- # print(i)
- #
- #
- #memoryview
- #usage:
- #>>> memoryview(b'abcd')
- #<memory at 0x104069648>
- #在进行切片并赋值数据时,不需要重新copy原列表数据,可以直接映射原数据内存,
- import time
- for n in (100000, 200000, 300000, 400000):
- data = b'x'*n
- start = time.time()
- b = data
- while b:
- b = b[1:]
- print('bytes', n, time.time()-start)
- for n in (100000, 200000, 300000, 400000):
- data = b'x'*n
- start = time.time()
- b = memoryview(data)
- while b:
- b = b[1:]
- print('memoryview', n, time.time()-start)
内置函数实例
Python6 - 函数总结的更多相关文章
- 一起入门python6之函数
今天我们来学习新的一篇吧,那便是“函数(function)”我们用def来定义一个函数,以案例说话.>>> def name(x): #定义一个“name”的函数. ...
- 自学Python之路-Python基础+模块+面向对象+函数
自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的 ...
- 自学Python6.1-模块简介
自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...
- 自学Python6.2-类、模块、包
自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...
- 自学Python6.3-内置模块(1)
自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...
- python全栈开发 生成器 :生成器函数,推导式及生成器表达式
python 全栈开发 1.生成器函数 2.推导式 3.生成器表达式 一.生成器函数 1.生成器: 生成器的本质就是迭代器 (1)生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), ...
- Day 14 列表推导式、表达器、内置函数
一. 列表推导式# l1 = []# for i in range(1,11):# l1.append(i)# print(l1)# #输出结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, ...
- 巨蟒python全栈开发-第12天 生成器函数 各种推导式 yield from
一.今日主要内容总览(重点) 1.生成器(目的:帮助我们创建对象) (1)生成器的本质就是迭代器 (2)一个一个的创建对象 (3)创建生成器的方式: 1.生成器函数 2.通过生成器表达式来获取生成器 ...
- python 基础篇 14 程程器表达式 内置函数
昨日内容回顾 可迭代对象: 内部含有__iter__方法的就是可迭代对象. 可迭代对象不能取值,因为内部不含有__next__方法. 可迭代对象 ---> ...
随机推荐
- 洛谷 P2257 YY的GCD
洛谷 P2257 YY的GCD \(solution:\) 这道题完全跟[POI2007]ZAP-Queries (莫比乌斯反演+整除分块) 用的一个套路. 我们可以列出答案就是要我们求: \(ans ...
- _vimrc(VimScript脚本语言学习)
Windows下 syntax on "高亮 "缩进 set cindent "set cin set smartindent "set si set auto ...
- 微信小程序的页面渲染(if/for)
下面,粗略的介绍一下微信小程序的条件渲染.列表渲染.数据绑定等,详细的内容大家可以去看微信小程序的API,在此只做简单描述,希望能帮助到大家 条件渲染 <!--wxml--> <vi ...
- PLSQL_day01
declare begin dbms_output.put_line('Hello world') end;
- JS window对象的top、parent、opener含义介绍
1.top该变更永远指分割窗口最高层次的浏览器窗口.如果计划从分割窗口的最高层次开始执行命令,就可以用top变量. 2.openeropener用于在window.open的页面引用执行该window ...
- 使用密钥认证机制远程登录Linux
密钥认证机制 创建存放key的文件 1)创建目录 /root/.ssh 并设置权限 [root@localhost ~]# mkdir /root/.ssh mkdir 命令用来创建目录,以后会详细介 ...
- Salt Document学习笔记1
原文来自Salt Documentation,作者是 Thomas Hatch),我摘抄部分可能今后会用到或适合入门到精通的一些原文段落,简单翻译后发上来,便于查阅和研究 一.原理方面:The net ...
- 【转】assert预处理宏与预处理变量
assert assert是一个预处理宏,由预处理器管理而非编译器管理,所以使用时都不用命名空间声明,如果你写成std::assert反而是错的.使用assert需要包含cassert或assert. ...
- svn数据库自动备份脚本
创建一个存放备份数据的路径 mkdir /data/svnbak -p 采用shell脚本的方式实现自动备份 #vim backup.sh #!/bin/bash log="/data/sv ...
- discuz3.4:在Centos6.5中安装过程
参考文章:https://www.cnblogs.com/hehongbin/articles/5741270.html https://www.cnblogs.com/mitang/p/552454 ...