跟老齐学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 pickle模块用法实例
Apr 14 Python
在Python中测试访问同一数据的竞争条件的方法
Apr 23 Python
Python获取任意xml节点值的方法
May 05 Python
Python2.x与Python3.x的区别
Jan 14 Python
Python3.2模拟实现webqq登录
Feb 15 Python
Python列表list内建函数用法实例分析【insert、remove、index、pop等】
Jul 24 Python
关于Python中空格字符串处理的技巧总结
Aug 10 Python
Python升级导致yum、pip报错的解决方法
Sep 06 Python
Python hashlib常见摘要算法详解
Jan 13 Python
Python实现加密的RAR文件解压的方法(密码已知)
Sep 11 Python
python实现AdaBoost算法的示例
Oct 03 Python
python读取图片颜色值并生成excel像素画的方法实例
Feb 19 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
一个简单的自动发送邮件系统(一)
2006/10/09 PHP
Yii框架弹出窗口组件CJuiDialog用法分析
2017/01/07 PHP
php计算多个集合的笛卡尔积实例详解
2017/02/16 PHP
PHP的反射机制实例详解
2017/03/29 PHP
PHP时间处理类操作示例
2018/09/05 PHP
JavaScript中的16进制字符(改进)
2011/11/21 Javascript
自写的jQuery异步加载数据添加事件
2014/05/15 Javascript
JS实现至少包含字母、大小写数字、字符的密码等级的两种方法
2015/02/03 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
JavaScript深度复制(deep clone)的实现方法
2016/02/19 Javascript
JavaScript闭包和范围实例详解
2016/12/19 Javascript
js实现省份下拉菜单效果
2017/02/15 Javascript
为什么说JavaScript预解释是一种毫无节操的机制详析
2018/11/18 Javascript
使用layer模态框给新页面传值的方法
2019/09/27 Javascript
python使用any判断一个对象是否为空的方法
2014/11/19 Python
Python的地形三维可视化Matplotlib和gdal使用实例
2017/12/09 Python
Python中使用支持向量机(SVM)算法
2017/12/26 Python
对python中array.sum(axis=?)的用法介绍
2018/06/28 Python
Windows下python3.7安装教程
2018/07/31 Python
Pandas之Dropna滤除缺失数据的实现方法
2019/06/25 Python
pytorch方法测试详解——归一化(BatchNorm2d)
2020/01/15 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
2020/01/21 Python
从多个tfrecord文件中无限读取文件的例子
2020/02/17 Python
GDAL 矢量属性数据修改方式(python)
2020/03/10 Python
Django Channel实时推送与聊天的示例代码
2020/04/30 Python
从python读取sql的实例方法
2020/07/21 Python
Python 如何创建一个简单的REST接口
2020/07/30 Python
cookies应对python反爬虫知识点详解
2020/11/25 Python
北美领先的智能产品购物网站:Wellbots
2018/06/11 全球购物
医学检验专业个人求职信范文
2013/12/04 职场文书
四年级数学教学反思
2014/02/02 职场文书
经济职业学院毕业生自荐书
2014/03/17 职场文书
2014年资料员工作总结
2014/11/18 职场文书
入党函调证明材料
2015/06/19 职场文书
2016年6.5世界环境日宣传活动总结
2016/04/01 职场文书
Spring IOC容器Bean的作用域及生命周期实例
2022/05/30 Java/Android