Python运维开发基础10-函数基础【转】
一,函数的非固定参数
1.1 默认参数
在定义形参的时候,提前给形参赋一个固定的值。
#代码演示:
def test(x,y=2): #形参里有一个默认参数
print (x)
print (y)
test(3)
#输出结果
3
2
默认参数特点:
调用函数的时候,默认参数非必须传递
默认参数的用途:
- 安装一个软件的时候,都会有所谓默认安装和自定义安装之类的选项。那么默认安装是什么呢?就是软件预先已经设定好了安装的内容参数,你只要执行就会按照默认参数的方式进行安装。
- 连接数据库的端口号,或者xshell链接Linux默认的22端口等等
1.2 参数组
元组式参数组
不知道同学们想到了没有,假如我们在定义实参的时候,想让实参的个数可以不固定。那么我们该如何定义形参呢?
#代码演示:
def test(*args) : #以*开头定义实参
print(args)
test(1,2,3,4,5)
test(*[1,2,3,4,5,5]) #特殊调用
#输出结果
[root@localhost chen]# python3 file.py
(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5, 5)
综上,我们可知,当我们需要传递多个实参,而又无法确定实参的个数时,我们可以采用*号加上变量名的形式定义形参,这样形参就可以接收无限量的实参。并把他们放到一个元组里。
#代码演示:
def test(x,*Mr_chen) :
print (x)
print (Mr_chen)
test(1,2,3,4,5,6,7)
#输出结果
[root@localhost chen]# python3 file.py
1 #位置参数按顺序对应
(2, 3, 4, 5, 6, 7)
结论:元组式参数组就是将多个位置参数转化成元组进行接收的过程。
键值式参数组
#代码演示
def test(**kwargs) :
print (kwargs)
test(name="Mr.chen",age="33",sex="男")
test(**{"name":"alex","age":8}) #特殊调用 #直接以参数组方式传递
#输出结果
[root@localhost chen]# python3 file.py
{'name': 'Mr.chen', 'sex': '男', 'age': '33'}
{'name': 'alex', 'age': 8}
思考
如果我们在函数体里要取所传递的字典的值,那么我们是不是也能按照字典取值的方式呢?
#代码演示:
def test(**kwargs) :
print (kwargs)
print (kwargs["name"])
print (kwargs["age"])
print (kwargs["sex"])
test(name="Mr.chen",age="33",sex="男")
test(**{"name":"alex","age":8,"sex":"男"})
#输出结果
[root@localhost chen]# python3 file.py
{'age': '33', 'name': 'Mr.chen', 'sex': '男'}
Mr.chen
33
男
{'age': 8, 'name': 'alex', 'sex': '男'}
alex
8
男
结论:键值式参数组就是将多个关键字参数转化成字典进行接收的过程。
参数组的用途:
在最早我们设计软件的时候,刚开始也许我们估计的形参个数刚好够用,但是到了软件后期,我们也许会发现形参的个数不够了。那么,为了不总是动不动就修改源代码,我们可以多定义一个参数组,来接收多余的实参。
1.3 练习:参数的混合应用示例
请同学们判断以下调用示例正确与否
#例1
def test(name,**kwargs) :
print (name)
print (kwargs)
test(name="Mr.chen")
#例2
def test(name,**kwargs) :
print (name)
print (kwargs)
test("Mr.chen")
#例3
def test(name,**kwargs) :
print (name)
print (kwargs)
test("Mr.chen",18)
#例4
def test(name,**kwargs) :
print (name)
print (kwargs)
test("Mr.chen",age=18,sex="man")
#例5
def test(name,age=18,**kwargs) :
print (name)
print (age)
print (kwargs)
test("Mr.chen")
#例6
def test(name,age=18,**kwargs) :
print (name)
print (age)
print (kwargs)
test("Mr.chen",22,age=26)
#例7
def test(name,age=18,**kwargs) :
print (name)
print (age)
print (kwargs)
test("Mr.chen",22,sex="man")
#例8
def test(name,age=18,**kwargs,sex="man") :
print (name)
print (age)
print (sex)
print (kwargs)
test("Mr.chen",22,sex="man")
#例9
def test(name,age=18,**kwargs) :
print (name)
print (age)
print (kwargs)
test("Mr.chen",sex="man",hobby="Tom",age=22)
#例10
def test(name,age=18,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
test("Mr.chen",sex="man",hobby="Tom",age=22)
#例11
def test(name,age=18,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
test(name="Mr.chen",22,sex="man",44)
#例12
def test(name,age=18,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
test("Mr.chen",22,sex="man",44)
#例13
def test(name,age=18,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
test("Mr.chen",22,44,sex="man")
#例14
def test(age=18,name,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
test("Mr.chen")
#例15
def test(name,age=18,**kwargs,*args) :
print (name)
print (age)
print (args)
print (kwargs)
test("Mr.chen")
特别提示:
- 在写形参的时候,必须按照位置参数,关键字参数,元组式参数组,键值式参数组的顺序。
- 在写实参的时候位置参数必须在关键字参数的前边,并且已经被位置参数一一对应赋值的形参,不能再被关键字参数赋值。
1.4 Python解释器的解析顺序
同学们比较下面的两个例子,看看运行的结果有何不同?分析下不同的原因。
#例1
def test(name,age=18,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
logger("TEST")
def logger(sorce) :
print ("这是一个{}".format(sorce))
test("Mr.chen",22,"TOM",sex="man")
#例2
def test(name,age=18,*args,**kwargs) :
print (name)
print (age)
print (args)
print (kwargs)
logger("TEST")
test("Mr.chen",22,"TOM",sex="man")
def logger(sorce) :
print ("这是一个{}".format(sorce))
二,作用域,局部与全局变量
全局变量:在函数体外定义赋值的变量
局部变量:在函数体内定义赋值的变量
#代码演示
def change_name(name) :
print (sex) #打印全局变量
print ("before change",name) #打印传递进来的全局变量
name = "Mr.chen" #修改传递进来的全局变量的值
age = 23 #局部变量
print ("after change",name) #修改后的全局变量仅局部生效
name = "yunjisuan" #全局变量
sex = "man" #全局变量
change_name(name)
print (name) #输出全局变量
#输出结果
[root@localhost chen]# python3 file.py
man
before change yunjisuan
after change Mr.chen
yunjisuan #函数体修改后的全局变量未在全局生效
- 从上边的代码示例来看,我们发现全局变量sex可以直接在函数体内被打印输出。然后函数体内的变量name的值则不能生效于函数体外。
- 或许同学们感觉很懵逼,下面我们来慢慢分拆理解这个过程
#例1:
def change_name() :
print (name)
name = "yunjisuan"
change_name()
print (name)
#输出结果
[root@localhost chen]# python3 file.py
yunjisuan
yunjisuan
结论1:在函数体外赋值的变量我们称为全局变量,变量的赋值生效于全局范围,因此,不论函数体内还是函数体外,我们都可以直接调用输出它的值。
#例2
def change_name() :
age = 18
print (name)
print (age)
name = "yunjisuan"
change_name()
print (name)
#输出结果
[root@localhost chen]# python3 file.py
yunjisuan
18
yunjisuan
结论2:函数体内赋值的变量我们可以在函数体内调用并输出它的值。
概念扩展:但是,我们不能在函数体外来调用输出它。演示如下:
#代码演示
def change_name() :
age = 18
print (name)
print (age)
name = "yunjisuan"
change_name()
print (name)
print (age) #输出函数体内定义的变量
#输出结果
NameError: name 'age' is not defined #age未在全局定义
假如,我们要在全局应用一个在函数体内定义的变量,那么我们该如何做呢?
#例3
def change_name() :
age = 18
print (name)
print (age)
return age #我们需要将函数体内的age的值返回
name = "yunjisuan"
age = change_name() #赋值给全局的age变量
print (name)
print (age)
#输出结果
[root@localhost chen]# python3 file.py
yunjisuan
18
yunjisuan
18
结论3:要在函数体外应用一个局部变量,那么我们需要通过return来将局部变量的值返回,并赋值给一个全局变量,然后输出它。
我们思考一下:
假如一个变量已经在全局被定义了,我们还能创建一个同样的局部变量吗?
#例4
def change_name() :
name = "Mr.chen"
print (name)
name = "yunjisuan"
change_name()
print (name)
#输出结果
[root@localhost chen]# python3 file.py
Mr.chen #函数体内的输出
yunjisuan #函数体外的输出
结论4:当我们在函数体内赋值了一个和函数体外的全局变量名字完全一样的局部变量时。局部变量的生效范围只能发生在函数体内,而函数体外则是全局变量的生效范围。
我们继续思考一下:
假如一个变量已经在函数体内被定义了。那么我们还能按照全局规则调用它吗?
#例5
def change_name() :
print (name) #输出全局变量name
name = "Mr.chen"
print (name)
name = "yunjisuan"
change_name()
print (name)
#输出结果
UnboundLocalError: local variable 'name' referenced before assignment #本地变量name没有被定义
结论5:一旦一个变量名在函数体内被定义,那么它就会被这个函数体认为是局部变量。你只要在函数体内输出它,都会被认为是局部变量,而不是全局变量。
我们还得思考一下:
假如我们需要将局部变量的值带回到全局生效,那么我们有没有什么办法呢?
方法一: global关键字
#代码演示:
def change_name() :
global name #将局部变量的作用域声明全局生效
name = "Mr.chen"
print (name)
name = "yunjisuan"
change_name()
print (name)
#输出结果
[root@localhost chen]# python3 file.py
Mr.chen
Mr.chen
方法二: return关键字
#代码演示
def change_name() :
name = "Mr.chen"
print (name)
return name
name = "yunjisuan"
print (name)
name = change_name()
print (name)
#输出结果
[root@localhost chen]# python3 file.py
yunjisuan
Mr.chen
Mr.chen
结论6:假如我们需要将局部变量的值带回给全局变量并让他全局能够生效。那么我们需要通过return关键字将局部变量的值返回给全局变量并赋值。
我们最后思考一下:
假如我们需要在函数体内调用全局变量的值,然而在这个函数体内我们已经定义过了和全局变量名字完全一样的局部变量,而且在函数体整个运行的过程中,这个变量的值也许会发生改变。那么通常我们又该如何做呢?
#例6
def change_name(age) :
if age == 22 :
age = 44
return age
return age
age = 22
age = change_name(age)
print (age)
#输出结果
[root@localhost chen]# python3 file.py
44
结论7:如果我们想要将全局被定义的变量经过函数体内的代码进行判断,并且将判断的结果返回给全局,那么我们需要将全局变量以实参的方式传递给函数体的形参进行接收,最后将判断的结果返回到全局并赋值。
特别提示:
- 在我们写代码的时候,一定不要用global的方式将局部变量声明全局生效。这是因为,一旦global我们用多了,你就会忘记哪个局部变量被生效过了。一旦发生这样的事情,当我们代码写的很多了以后,你就会频繁发生变量冲突,这样非常麻烦。
- 所以,我们在写代码的时候,一定要养成好的习惯。采用传参后return的方式将结果返回给全局变量从而全局生效。
Python运维开发基础10-函数基础 - 陈思齐 - 博客园
https://www.cnblogs.com/chensiqiqi/p/9163060.html
Python运维开发基础10-函数基础【转】的更多相关文章
- Python运维开发基础09-函数基础【转】
上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...
- Python运维开发基础07-文件基础【转】
一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...
- Python运维开发基础06-语法基础【转】
上节作业回顾 (讲解+温习120分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 添加商家入口和用户入口并实现物 ...
- Python运维开发基础05-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python # -*- coding:utf-8 -*- # author:Mr.chen import os,time Tag = ...
- Python运维开发基础04-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 仅用列表+循环实现“简单的购物车程 ...
- Python运维开发基础03-语法基础 【转】
上节作业回顾(讲解+温习60分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen #只用变量和字符串+循环实现“用户登陆 ...
- Python运维开发基础02-语法基础【转】
上节作业回顾(讲解+温习60分钟) #!/bin/bash #user login User="yunjisuan" Passwd="666666" User2 ...
- Python运维开发基础01-语法基础【转】
开篇导语 整个Python运维开发教学采用的是最新的3.5.2版,当遇到2.x和3.x版本的不同点时,会采取演示的方式,让同学们了解. 教学预计分为四大部分,Python开发基础,Python开发进阶 ...
- Python运维开发基础01-语法基础
标签(空格分隔): Mr.chen之Python3.0执教笔记(QQ:215379068) --仅供北大青鸟内部学习交流使用 开发不是看出来的,开发一定是练出来的: 想学好开发,没有捷径可走,只有不断 ...
随机推荐
- idea代码回退到前面的版本
好多时候一个项目添加了新功能,导致整个项目不能运行,而之前的版本又没有保存.怎么办了?回退到以前的版本就OK啦, 没错IDEA就是这个智能化. 第一步:点击项目名称->右键->选择Loca ...
- OPCServer:使用KEPServer
实际OPCServer使用(450M,中文,破解时间限制):KEPServer V6,百度网盘 ,密码: ykj2 本文为Java实现OPC通信的一部分 KEPServer中文官网 KEPServer ...
- 5年GTD自我管理经验,一块听听
我在胜利油田做了20多年的油田信息化工作,以前的我经常处于这样一种状态: 当我正在做着手边的一项事情时,头脑里却不断地蹦出来其它的事务,让我烦心不已,焦虑不安:PPT经常要拖到汇报当天的凌晨才做完,有 ...
- Silverlight中字典的使用
通过值搜索字典中的项: FristOfDefault返回序列中满足条件的第一个元素:如果未找到这样的元素,则返回默认值.
- SQL Server进阶(十二)函数
概述 函数有且只有一个输入参数和一个返回值,而存储过程没有这个限制: 返回表变量的函数可以当做VIEW或者临时表用在WHERE/HAVING/SELECT/JOIN语句中而存储过程不可以: 存储过程中 ...
- 开源框架.netCore DncZeus学习(二)配置连接
配置连接字符串,update-database,初始数据后,访问报错,提示offset错误.因为本机上使用的sql2008. .net Core 2.X中的EF访问sqlserver2008默认使用的 ...
- 今天终于想明白为什么java包要倒着写
比如 com.baidu.video,因为java内部实际上是以文件夹形式存在的,是按com,baidu,video依次生成文件夹的具体功能的是子文件夹,所以要倒着写.
- treap基本操作
利用rand保持堆的特性 const int N=; int ls[N],rs[N],v[N],p[N],cnt[N],siz[N]; // 权值 优先级 inline void update(int ...
- luogu 2704 炮兵阵地 状压dp
状压的基础题吧 第一次看感觉难上天,后来嘛就.. 套路:先根据自身状态筛出可行状态,再根据地图等其他限制条件筛选适合的状态加入答案 f i,j,k 分别代表 行数,本行状态,上行状态,再累加答案即可 ...
- 【Python】Xml To Excel
[Python3] 之前做的入门练习里有一题将excel文件转化为xml文件,这回补上逆向转换→xml to excel 用的还是beautifulsoup. 主要还是:①读取待处理文件文本内容 ②处 ...