python基础教程总结5——函数
1.函数创建
1).函数代码块以def关键词开头,后接函数标识符名称和圆括号()
2).任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数
3).函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明
4).函数内容以冒号起始,并且缩进
5).Return[expression]结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回
None
- def functionname( parameters ):
- "函数_文档字符串"
- function_suite
- return [expression]
2.函数参数
形参:写在def语句中函数名后面的变量通常叫做函数的形式参数,
实参:而调用函数的时候提供的值是实际参数,或者称为参数; 参数存储在局部作用域(local scope)内。
2.1 参数的改变:在函数内为参数赋予新值不会改变外部任何变量的值。
- def try_to_change(n):
- n = 'Mr. Gumby'
- name = 'Mrs Entity'
- try_to_change(name)
- print name
- def try_to_change(n):
运行结果打印"Mrs Entity“。在try_to_change内,参数n获得了新值,但是它没有影响到name变量。n实际上是个完全不同的变量。
2.2关键字参数:通常我们所使用的参数都叫做位置参数,因为它们的位置很重要——事实上比它们的名字更重要。因此python引入了使用参数名来提供参数,这类使用参数名提供参数就叫做关键字参数。
- def hello_1(greeting,name):
- print '%s, %s!' %(greeting,name)
- def hello_2(name,greeting):
- print '%s, %s!' %(name,greeting)
- print hello_1('hello','world')
- print hello_2('hello','world')
- #运行结果:
- hello, world
- None
- hello, world
- None
- def hello_1(greeting,name):
- print '%s, %s!' %(greeting,name)
- def hello_2(name,greeting):
- print '%s, %s!' %(name,greeting)
- hello_1(greeting='hello',name='world')
- hello_1(name='world',greeting='hello')
- #结果:
- hello, world
- hello, world
- def hello_1(greeting,name):
2.3 参数的默认值:前面提到了关键字参数的一些作用,但关键字参数最厉害的地方在于可以在函数中给参数提供默认值:
- def hello_3(greeting='Hello',name='world'):
- print '%s, %s!' %(greeting,name)
- hello_3()
- hello_3('greeting')
- hello_3('greeting','universe')
#结果:
- Hello, world!
- greeting, world!
- greeting, universe!
2.4 并非真正函数的函数:数学意义上的函数,总在计算其参数后返回点什么。python的有些函数却并不返回任何东西。
- def test():
- print 'This is printed'
- return
- print 'This is not'
- x = test()
- print x
- #运行结果:
- This is printed
- None
这里的return语句只起到结束函数的作用,第二个print语句被跳过了。return语句不返回任何值,那么x又引用什么呢?对,就是第二行的None。所以,所有的函数其实都返回了东西:当不需要它们返回值的时候,它们就返回None。
- 1 #coding:utf-8 #设置python文件的编码为utf-8,这样就可以写入中文注释
- 2 def foo(arg1,*tupleArg,**dictArg):
- 3 print "arg1=",arg1 #formal_args
- 4 print "tupleArg=",tupleArg #()
- 5 print "dictArg=",dictArg #[]
- 6 foo("formal_args")
tupleArg前面“*”表示这个参数是一个元组参数,从程序的输出可以看出,默认值为();
dicrtArg前面有“**”表示这个字典参数(键值对参数)。
可以把tupleArg、dictArg看成两个默认参数。多余的非关键字参数,函数调用时被放在元组参数tupleArg中;多余的关键字参数,函数调用时被放字典参数dictArg中。
- 1 #coding:utf-8 #设置python文件的编码为utf-8,这样就可以写入中文注释
- 2 def foo(arg1,arg2="OK",*tupleArg,**dictArg):
- 3 print "arg1=",arg1
- 4 print "arg2=",arg2
- 5 for i,element in enumerate(tupleArg):
- 6 print "tupleArg %d-->%s" % (i,str(element))
- 7 for key in dictArg:
- 8 print "dictArg %s-->%s" %(key,dictArg[key])
- 9
- 10 myList=["my1","my2"]
- 11 myDict={"name":"Tom","age":22}
- 12 foo("formal_args",arg2="argSecond",a=1)
- 13 print "*"*40
- 14 foo(123,myList,myDict)
- 15 print "*"*40
- 16 foo(123,rt=123,*myList,**myDict)

输出为:
从上面的程序可以看出:
(1)如代码第16行。
参数中如果使用“*”元组参数或者“**”字典参数,这两种参数应该放在参数列表最后。并且“*”元组参数位于“**”字典参数之前。
关键字参数rt=123,因为函数foo(arg1,arg2="OK",*tupleArg,**dictArg)中没有rt参数,所以最后也归到字典参数中。
(2)如代码第14行。
元组对象前面如果不带“*”、字典对象如果前面不带“**”,则作为普通的对象传递参数。
多余的普通参数,在foo(123,myList,myDict)中,123赋给参数arg1,myList赋给参数arg2,多余的参数myDict默认为元组赋给myList。
在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数,关键字参数。
- def func(a, b, c=0, *args, **kw):
- print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。
- >>> func(1, 2)
- a = 1 b = 2 c = 0 args = () kw = {}
- >>> func(1, 2, c=3)
- a = 1 b = 2 c = 3 args = () kw = {}
- >>> func(1, 2, 3, 'a', 'b')
- a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
- >>> func(1, 2, 3, 'a', 'b', x=99)
- a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
最神奇的是通过一个tuple和dict,你也可以调用该函数:
- >>> args = (1, 2, 3, 4)
- >>> kw = {'x': 99}
- >>> func(*args, **kw)
- a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}
所以,对于任意函数,都可以通过类似func(*args, **kw)
的形式调用它,无论它的参数是如何定义的。
*args
是可变参数,args接收的是一个tuple;
**kw
是关键字参数,kw接收的是一个dict。
参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
3. 作用域
3.1作用域分类
python中的作用域分4种情况:搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。
L:local,局部作用域,即函数中定义的变量;
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G:globa,全局变量,就是模块级别定义的变量;
B:built-in,系统固定模块里面的变量,比如int, bytearray等。
- x = int(2.9) # int built-in
- g_count = 0 # global
- def outer():
- o_count = 1 # enclosing
- def inner():
- i_count = 2 # local
3.2 作用域的产生
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码:
- if True:
- x = 1;
- print(x)
- # 1
这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用。
- def test():
- x2 = 2
- print(x2)
- # NameError: name 'x2' is not defined
3.3 变量的修改
一个不在局部作用域里的变量默认是只读的,如果试图为其绑定一个新的值,python认为是在当前的局部作用域里创建一个新的变量,也就是说在当前局部作用域中,如果直接使用外部作用域的变量,那么这个变量是只读的,不能修改,如:
- count = 10
- def outer():
- print(count)
- count = 100
- print(count)
- outer()
- #UnboundLocalError: local variable 'count' referenced before assignment
这里第一个print中,使用到了外部作用域的count,这样后面count就指外部作用域中的count了,再修改就会报错。 如果没使用过这个变量,而直接赋值,会认为是新定义的变量,此时会覆盖外部作用域中变量,如:
- count = 10
- def outer():
- count = 100
- print(count)
- outer()
- #
内部作用域中直接声明了count=100,后面使用count都是内部作用域的了。
3.4 global关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:
- 1 count = 10
- 2 def outer():
- 3 global count
- 4 print(count)
- 5 count = 100
- 6 print(count)
- 7 outer()
- 8 #10
- 9 #100
3.5 nonlocal关键字
global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了
- 1 def outer():
- 2 count = 10
- 3 def inner():
- 4 nonlocal count
- 5 count = 20
- 6 print(count)
- 7 inner()
- 8 print(count)
- 9 outer()
- 10 #20
- 11 #20
3.6 小结:
(1)变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个关键字,就能完美的实现闭包了。
python基础教程总结5——函数的更多相关文章
- 《python基础教程(第二版)》学习笔记 函数(第6章)
<python基础教程(第二版)>学习笔记 函数(第6章) 创建函数:def function_name(params): block return values 记录函数:def f ...
- 改写《python基础教程》中的一个例子
一.前言 初学python,看<python基础教程>,第20章实现了将文本转化成html的功能.由于本人之前有DIY一个markdown转html的算法,所以对这个例子有兴趣.可仔细一看 ...
- python基础教程笔记—即时标记(详解)
最近一直在学习python,语法部分差不多看完了,想写一写python基础教程后面的第一个项目.因为我在网上看到的别人的博客讲解都并不是特别详细,仅仅是贴一下代码,书上内容照搬一下,对于当时刚学习py ...
- python基础教程(一)
之所以选择py交易有以下几点:1.python是胶水语言(跨平台),2.python无所不能(除了底层),3.python编写方便(notepad++等文本编辑器就能搞事情),4.渗透方面很多脚本都是 ...
- python基础教程(第二版)
开始学习python,根据Python基础教程,把里面相关的基础章节写成对应的.py文件 下面是github上的链接 python基础第1章基础 python基础第2章序列和元组 python基础第3 ...
- python基础教程1:入门基础知识
写在系列前,一点感悟 没有梳理总结的知识毫无价值,只有系统地认真梳理了才能形成自己的知识框架,否则总是陷入断片儿似的学习-遗忘循环中. 学习方法真的比刻苦"傻学"重要多了,而最重要 ...
- Python基础教程学习笔记:第一章 基础知识
Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...
- 【Python】Python基础教程系列目录
Python是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. 在现在的工作及开发当中,Python的使用越来越广泛,为了方便大家的学习,Linux大学 特推出了 <Python基 ...
- Python 基础教程
Python 基础教程 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年. 像P ...
随机推荐
- 2014 SCAU_ACM 暑期集训
暑期集训,希望能在这段时间获得对得起自己的提升吧 时间:7.11~8.30 集训各专题内容: 1.贪心,递推,基础DP(背包,区间DP,状态压缩DP(去年出了不少于2道铜牌题,看着办)) 2.搜索(B ...
- malloc,alloc,realloc之间的相似与区别
三个函数的申明分别是: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(si ...
- C语言学习总结
输出加法程序 #include<stdio.h> int main() { printf("#include<stdio.h>\n\n"); printf( ...
- Django 之 requirement.txt 依赖文件生成
通过依赖文件,别人在使用我们的项目时,不需要再一个个去安装所需模块,只需安装依赖文件即可. 1. 导出整个虚拟环境依赖 # 在项目根目录中,打开终端执行以下命令 # 生成 requirements.t ...
- 图解SynchronousQueue原理详解-非公平模式
SynchronousQueue原理详解-非公平模式 开篇 说明:本文分析采用的是jdk1.8 约定:下面内容中Ref-xxx代表的是引用地址,引用对应的节点 前面已经讲解了公平模式的内容,今天来讲解 ...
- ue4学习资料
官网中文 https://docs.unrealengine.com/latest/CHN/index.html 官网英文 https://docs.unrealengine.com/latest/I ...
- php UTF8 转字节数组,后使用 MD5 计算摘要
Hex.encodeHexString(md5.digest);按 UTF8 转字节数组,后使用 MD5 计算摘要,得到 16 字节数组,使用 Hex 转为长度为 32 的字符串,保持小写 bin2h ...
- webpack 打包和手动创建一个vue的项目
首先我们为啥要用webpack,为啥不用其他的打包的工具. 先听我捋捋, Webpack有人也称之为 模块打包机 ,由此也可以看出Webpack更侧重于模块打包,当然我们可以把开发中的所有资源(图片. ...
- 新的JSON / YAML插件:在JMeter中使用YAML
在JMS插件从jmeter-plugins.org捐赠给核心JMeter之后,JSON插件在Apache JMeter™版本4中被弃用.现在,我已更新此插件以支持新功能和新功能.在这个新版本中,两个插 ...
- python进阶04 装饰器、描述器、常用内置装饰器
python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...