跟老齐学Python之变量和参数


Posted in Python onOctober 10, 2014

那么什么这两个到底有什么区别和联系呢?我在网上搜了一下,发现很多说法,虽然大同小异,但是似乎只有下面这一段来自微软网站的比较高度抽象,而且意义涵盖深远。我摘抄过来,看官读一读,是否理解,虽然是针对VB而言的,一样有启发。

参数和变量之间的差异 (Visual Basic)
多数情况下,过程必须包含有关调用环境的一些信息。执行重复或共享任务的过程对每次调用使用不同的信息。此信息包含每次调用过程时传递给它的变量、常量和表达式。
若要将此信息传递给过程,过程先要定义一个形参,然后调用代码将一个实参传递给所定义的形参。 您可以将形参当作一个停车位,而将实参当作一辆汽车。 就像一个停车位可以在不同时间停放不同的汽车一样,调用代码在每次调用过程时可以将不同的实参传递给同一个形参。
形参表示一个值,过程希望您在调用它时传递该值。
当您定义 Function 或 Sub 过程时,需要在紧跟过程名称的括号内指定形参列表。对于每个形参,您可以指定名称、数据类型和传入机制(ByVal (Visual Basic) 或 ByRef (Visual Basic))。您还可以指示某个形参是可选的。这意味着调用代码不必传递它的值。
每个形参的名称均可作为过程内的局部变量。形参名称的使用方法与其他任何变量的使用方法相同。
实参表示在您调用过程时传递给过程形参的值。调用代码在调用过程时提供参数。
调用 Function 或 Sub 过程时,需要在紧跟过程名称的括号内包括实参列表。每个实参均与此列表中位于相同位置的那个形参相对应。

 

与形参定义不同,实参没有名称。每个实参就是一个表达式,它包含零或多个变量、常数和文本。求值的表达式的数据类型通常应与为相应形参定义的数据类型相匹配,并且在任何情况下,该表达式值都必须可转换为此形参类型。

看官如果硬着头皮看完这段引文,发现里面有几个关键词:参数、变量、形参、实参。本来想弄清楚参数和变量,结果又冒出另外两个东东,更混乱了。请稍安勿躁,本来这段引文就是有点多余,但是,之所以引用,就是让列位开阔一下眼界,在编程业界,类似的东西有很多名词。下次听到有人说这些,不用害怕啦,反正自己听过了。

在Python中,没有这么复杂。

看完上面让人晕头转向的引文之后,再看下面的代码,就会豁然开朗了。

>>> def add(x):     #x是参数

...     a = 10      #a是变量

...     return a+x

... 

>>> x = 3           #x是变量,只不过在函数之外

>>> add(x)          #这里的x是参数,但是它由前面的变量x传递对象3

13

>>> add(3)          #把上面的过程合并了

13

 至此,看官是否清楚了一点点。当然,我所表述不正确之处或者理解错误之处,也请看官不吝赐教,小可作揖感谢。

全局变量和局部变量

下面是一段代码,注意这段代码中有一个函数funcx(),这个函数里面有一个变量x=9,在函数的前面也有一个变量x=2

x = 2
def funcx():

    x = 9

    print "this x is in the funcx:-->",x
funcx()

print "--------------------------"

print "this x is out of funcx:-->",x

 那么,这段代码输出的结果是什么呢?看:

this x is in the funcx:--> 9

--------------------------

this x is out of funcx:--> 2

 从输出看出,运行funcx(),输出了funcx()里面的变量x=9;然后执行代码中的最后一行,print "this x is out of funcx:-->",x

特别要关注的是,前一个x输出的是函数内部的变量x;后一个x输出的是函数外面的变量x。两个变量彼此没有互相影响,虽然都是x。从这里看出,两个X各自在各自的领域内起到作用,那么这样的变量称之为局部变量。

有局部,就有对应的全部,在汉语中,全部变量,似乎有歧义,幸亏汉语丰富,于是又取了一个名词:全局变量

x = 2

def funcx():

    global x

    x = 9

    print "this x is in the funcx:-->",x
funcx()

    print "--------------------------"

    print "this x is out of funcx:-->",x

 以上两段代码的不同之处在于,后者在函数内多了一个global x,这句话的意思是在声明x是全局变量,也就是说这个x跟函数外面的那个x同一个,接下来通过x=9将x的引用对象变成了9。所以,就出现了下面的结果。
this x is in the funcx:--> 9
--------------------------
this x is out of funcx:--> 9

 好似全局变量能力很强悍,能够统帅函数内外。但是,要注意,这个东西要慎重使用,因为往往容易带来变量的换乱。内外有别,在程序中一定要注意的。

不确定参数的数量

在设计函数的时候,有时候我们能够确认参数的个数,比如一个用来计算圆面积的函数,它所需要的参数就是半径(πr^2),这个函数的参数是确定的。

然而,这个世界不总是这么简单的,也不总是这么确定的,反而不确定性是这个世界常常存在的。如果看官了解量子力学这个好多人听都没有听过的东西,那就理解真正的不确定性了。当然,不用研究量子力学也一样能够体会到,世界充满里了不确定性。不是吗?塞翁失马焉知非福,这不就是不确定性吗?

既然有很多不确定性,那么函数的参数的个数,也当然有不确定性,函数怎么解决这个问题呢?python用这样的方式解决参数个数的不确定性:

def add(x,*arg):

    print x         #输出参数x的值

    result = x

    print arg       #输出通过*arg方式得到的值

    for i in arg:

        result +=i

    return result
print add(1,2,3,4,5,6,7,8,9)    #赋给函数的参数个数不仅仅是2个

 运行此代码后,得到如下结果:
1                       #这是函数体内的第一个print,参数x得到的值是1
(2, 3, 4, 5, 6, 7, 8, 9) #这是函数内的第二个print,参数arg得到的是一个元组
45                      #最后的计算结果

 上面这个输出的结果表现相当不界面友好,如果不对照着原函数,根本不知道每行打印的是什么东西。自责呀。

从上面例子可以看出,如果输入的参数过多,其它参数全部通过*arg,以元组的形式传给了参数(变量)arg。请看官注意,我这里用了一个模糊的词语:参数(变量),这样的表述意思是,在传入数据的前,arg在函数头部是参数,当在函数语句中,又用到了它,就是变量。也就是在很多时候,函数中的参数和变量是不用那么太区分较真的,只要知道对象是通过什么渠道、那个东西传到了什么目标即可。

为了能够更明显地看出args(名称可以不一样,但是符号必须要有),可以用下面的一个简单函数来演示:

>>> def foo(*args):

...     print args      #打印通过这个参数得到的对象

... 

>>> #下面演示分别传入不同的值,通过参数*args得到的结果
>>> foo(1,2,3)

(1, 2, 3)
>>> foo("qiwsir","qiwsir.github.io","python")

('qiwsir', 'qiwsir.github.io', 'python')
>>> foo("qiwsir",307,["qiwsir",2],{"name":"qiwsir","lang":"python"})

('qiwsir', 307, ['qiwsir', 2], {'lang': 'python', 'name': 'qiwsir'})

 不管是什么,都一股脑地塞进了tuple中。

除了用*args这种形式的参数接收多个值之外,还可以用**kargs的形式接收数值,不过这次有点不一样:

>>> def foo(**kargs):

...     print kargs

...

>>> foo(a=1,b=2,c=3)    #注意观察这次赋值的方式和打印的结果

{'a': 1, 'c': 3, 'b': 2}

 如果这次还用foo(1,2,3)的方式,会有什么结果呢?

>>> foo(1,2,3)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: foo() takes exactly 0 arguments (3 given)

 看官到这里可能想了,不是不确定性吗?我也不知道参数到底会可能用什么样的方式传值呀,这好办,把上面的都综合起来。

>>> def foo(x,y,z,*args,**kargs):

...     print x   

...     print y

...     print z

...     print args

...     print kargs        

... 

>>> foo('qiwsir',2,"python")

qiwsir

2

python

()

{}

>>> foo(1,2,3,4,5)

1

2

3

(4, 5)

{}

>>> foo(1,2,3,4,5,name="qiwsir")

1

2

3

(4, 5)

{'name': 'qiwsir'}

 很good了,这样就能够足以应付各种各样的参数要求了。

Python 相关文章推荐
详解使用python的logging模块在stdout输出的两种方法
May 17 Python
Django 前后台的数据传递的方法
Aug 08 Python
numpy数组拼接简单示例
Dec 15 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
Sep 27 Python
python 检查是否为中文字符串的方法
Dec 28 Python
深入了解和应用Python 装饰器 @decorator
Apr 02 Python
Python3离线安装Requests模块问题
Oct 13 Python
Python笔记之观察者模式
Nov 20 Python
python使用paramiko实现ssh的功能详解
Mar 06 Python
Python Pandas数据分析工具用法实例
Nov 05 Python
python excel和yaml文件的读取封装
Jan 12 Python
浅谈Python基础之列表那些事儿
May 11 Python
跟老齐学Python之重回函数
Oct 10 #Python
跟老齐学Python之Python文档
Oct 10 #Python
跟老齐学Python之大话题小函数(2)
Oct 10 #Python
跟老齐学Python之大话题小函数(1)
Oct 10 #Python
Python警察与小偷的实现之一客户端与服务端通信实例
Oct 09 #Python
python中二维阵列的变换实例
Oct 09 #Python
python实现每次处理一个字符的三种方法
Oct 09 #Python
You might like
Thinkphp多文件上传实现方法
2014/10/31 PHP
centos 7.2下搭建LNMP环境教程
2016/11/20 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
2016/12/27 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
js arguments.callee的应用代码
2009/05/07 Javascript
一个简单的JavaScript数据缓存系统实现代码
2010/10/24 Javascript
JavaScript 程序编码规范
2010/11/23 Javascript
JS特殊函数(Function()构造函数、函数直接量)区别介绍
2013/05/19 Javascript
Javascript表格翻页效果实现思路及代码
2013/08/23 Javascript
QQ空间顶部折页撕开效果示例代码
2014/06/15 Javascript
JavaScript实现动态创建CSS样式规则方案
2014/09/06 Javascript
jQuery将多条数据插入模态框的示例代码
2014/09/25 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
jquery表单插件Autotab使用方法详解
2016/06/24 Javascript
从零开始搭建webpack+react开发环境的详细步骤
2018/05/18 Javascript
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
微信小程序页面间值传递的两种方法
2018/11/26 Javascript
使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部
2019/09/16 Javascript
centos下更新Python版本的步骤
2013/02/12 Python
Python中time模块与datetime模块在使用中的不同之处
2015/11/24 Python
Python日志模块logging基本用法分析
2018/08/23 Python
django中账号密码验证登陆功能的实现方法
2019/07/15 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
CSS3 animation实现逐帧动画效果
2016/06/02 HTML / CSS
Html5剪切板功能的实现代码
2018/06/29 HTML / CSS
html5记忆翻牌游戏实现思路及代码
2013/07/25 HTML / CSS
John Varvatos官方网站:设计师男士时装
2017/02/08 全球购物
英国演唱会订票网站:Ticket Selection
2018/03/27 全球购物
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
职务聘任书范文
2014/03/29 职场文书
奉献爱心演讲稿
2014/09/04 职场文书
乡镇党员干部群众路线对照检查材料思想汇报
2014/09/28 职场文书
2015年个人招商工作总结
2015/04/25 职场文书
虎兄虎弟观后感
2015/06/12 职场文书
sentinel支持的redis高可用集群配置详解
2022/04/01 Redis