一,函数的非固定参数

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-函数基础的更多相关文章

  1. Python运维开发基础10-函数基础【转】

    一,函数的非固定参数 1.1 默认参数 在定义形参的时候,提前给形参赋一个固定的值. #代码演示: def test(x,y=2): #形参里有一个默认参数 print (x) print (y) t ...

  2. Python运维开发基础09-函数基础【转】

    上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...

  3. Python运维开发基础07-文件基础【转】

    一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...

  4. Python运维开发基础06-语法基础【转】

    上节作业回顾 (讲解+温习120分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 添加商家入口和用户入口并实现物 ...

  5. Python运维开发基础05-语法基础【转】

    上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python # -*- coding:utf-8 -*- # author:Mr.chen import os,time Tag = ...

  6. Python运维开发基础04-语法基础【转】

    上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 仅用列表+循环实现“简单的购物车程 ...

  7. Python运维开发基础03-语法基础 【转】

    上节作业回顾(讲解+温习60分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen #只用变量和字符串+循环实现“用户登陆 ...

  8. Python运维开发基础02-语法基础【转】

    上节作业回顾(讲解+温习60分钟) #!/bin/bash #user login User="yunjisuan" Passwd="666666" User2 ...

  9. Python运维开发基础01-语法基础【转】

    开篇导语 整个Python运维开发教学采用的是最新的3.5.2版,当遇到2.x和3.x版本的不同点时,会采取演示的方式,让同学们了解. 教学预计分为四大部分,Python开发基础,Python开发进阶 ...

  10. Python运维开发基础01-语法基础

    标签(空格分隔): Mr.chen之Python3.0执教笔记(QQ:215379068) --仅供北大青鸟内部学习交流使用 开发不是看出来的,开发一定是练出来的: 想学好开发,没有捷径可走,只有不断 ...

随机推荐

  1. PLSQL使用SCN码恢复误删表数据

    #查询数据库当前的SCN码select current_scn from v$database 1250494 #将当前的SCN码减小后,根据SCN码查询误删数据表的数据情况#直至找到被删的数据为止s ...

  2. Bezier画线算法

    编译器:VS2013 描述:Bezier画线是利用导数相同拼接曲线,使曲线十分光滑,而不是随意拼接观赏性很差 主函数段 #include "stdafx.h" #include&l ...

  3. Bootstrap:目录

    ylbtech-Bootstrap:目录 1.返回顶部 1. https://getbootstrap.com/ 2. 2.返回顶部 1. http://www.runoob.com/bootstra ...

  4. linux修改文件系统挂载的目录

    比如想把已经挂载在home目录上的硬盘挂载到data目录上, 如下操作 #df -h(查看分区情况及数据盘名称) # mkdir /data(如果没有data目录就创建,否则此步跳过) # umoun ...

  5. Spark分析之MemoryStore

    private case class MemoryEntry(value: Any, size: Long, deserialized: Boolean) class MemoryStore(bloc ...

  6. Spark 编程模型(下)

    创建Pair RDD 什么是Pair RDD 创建Pair RDD Pair RDD的转化操作 Pair RDD的转化操作1 在xshell启动 reduceByKey的意思是把相同的key的valu ...

  7. Samba 简介

    SMB 代表的是服务器消息块 (Server Message Block),它是用于在 Windows 上共享文件的协议的原始名称. CIFS 代表公共 Internet 文件系统 (Common I ...

  8. sql server查看表占用索引空间(小技巧)

    选择表右键—属性—存储—索引空间

  9. foreach的使用

    //foreach循环语句,常用来遍历数组,一般有两种使用方法:不取下标,取下标 //不取下表 foreach(数组 as 值) { //执行的程序 echo 值; } //取下标 foreach(数 ...

  10. 异步与websocket

    异步与WebSockets 知识点 理解同步与异步执行过程 理解异步代码的回调写法与yield写法 Tornado异步 异步Web客户端AsyncHTTPClient tornado.web.asyn ...