设为首页 收藏本站
查看: 640|回复: 0

[经验分享] python之函数基础

[复制链接]

尚未签到

发表于 2017-4-25 09:06:24 | 显示全部楼层 |阅读模式
从定义开始
  众所周知,函数是可以重用的程序段,它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块。
  python的函数是用def关键字来定义,主要包括:函数名、函数参数、函数体、函数返回值。

#!/usr/bin/env python
def foo():
return 1
print foo()
  以上例子的运行结果为:

1
  该例子中,函数名为foo, 我们通过foo()来调用该函数,打印返回值1

函数Scope
  python函数运行的时候,会创建自己的scope,即作用域(或者说函数有自己的namespace,即命名空间)。执行函数时,如果在函数体中遇到了变量名,python首先会在该函数的namespace内寻找该变量。
  python有一些内置函数,可以让我们来查看函数的namespaces,下面看一个例子,可以查看函数的local 和global 作用域。

#!/usr/bin/env python
a_string = "This is a global variable"
def foo():
print "locals:"
print locals()
print "globals:"
print globals() # doctest: +ELLIPSIS
foo() # 2
  执行结果:

globals:
{'foo': <function foo at 0x19c100c8>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': './2.py', 'a_string': 'This is a global variable', '__name__': '__main__', '__package__': None, '__doc__': None}
locals:
{}
  可以看到,内建函数globals返回的是一个dict,里面是全局性的一些变量(注意:我们定义的a_string也在里面,a_string是在函数外定义的)。代码里的#2处,调用了foo函数,里面的locals函数返回的是函数自己的namespace(foo中没有定义任何变量,所以是空的)

变量分辨规则
  在函数内部也可以访问global变量。python的作用域规则是:
  1. 变量在创建时,local作用域中默认创建的是local变量
  2. 在local作用域(scope)中访问变量时,首先在local作用域中寻找变量,然后在所有外围作用域中寻找变量。
  3. 在local作用域中修改变量时,默认是在local作用域寻找该变量,如果找不到,则新建一个变量。除非声明要修改的是global变量。
  下面的例子是在foo函数里打印global变量。

#!/usr/bin/env python
a_string = "This is a global variable"
def foo():
print locals()
print a_string #1
foo()
  执行结果:

{}
This is a global variable
  在foo函数里,先打印了locals,是空的。然后在#1处,打印a_string这个变量。这时候发生以下事情:
  1. python先在locals里面寻找,locals是空的,所以找不到。
  2.python在globals里面寻找,可以找到a_string,然后获得值,打印。
  再看一个例子:

#!/usr/bin/env python
a_string = "This is a global variable"
def foo():
a_string = "test" #1
print locals()
print a_string #2

def foo1():
global a_string #4
a_string = "Oh. global variable has been changed in foo1."  #5
foo()
print a_string #3
print "---------------------"
foo1()
print a_string#6
  执行结果为:

{'a_string': 'test'}
test
This is a global variable
---------------------
Oh. global variable has been changed in foo1.
  上面的代码中,有以下几个要点:
  1. #1是要给a_string赋值(即修改变量值),先在locals中寻找a_tring, 没有找到,则新创建local变量。所以打印locals时,结果为:{'a_string': 'test'} 。
  2. #2处打印时,按照我们之前说的变量分辨规则, 先从locals中寻找a_tring变量,在#1处有定义,所以直接打印
  3.#3处不在任何函数中,位于全局作用域,所以直接查找globals,找到了a_string,打印。
  4.#4处声明了一个全局变量(a_string之前已经声明,这里表示在local作用域中使用全局a_string)
  #5处修改a_string, 因为#4中声明了a_string是全局的,所以修改a_string之后,#6处打印的是修改后的值

变量生存周期

#!/usr/bin/env python
def foo():
x = 1
foo()
print x # 1
  执行结果:

Traceback (most recent call last):
File "./5.py", line 6, in <module>
print x # 1
NameError: name 'x' is not defined
  变量都是有生存周期(lifetime)的,变量的生存周期与变量声明时的作用域息息相关。其作用域销毁时,变量也就销毁了。
  上面的例子主要有以下要点:
  1. x是在foo函数内定义的,在foo的locals中存在,因此,其作用域是foo函数的作用域。
  也就是说:foo运行时,locals创建,x位于locals中,结束后,foo的locals被销毁,x不在了。
  2. #1处打印x,#1位于全局作用域,因此,其在globals中寻找x,没有找到,所以会报错。

函数参数与参量
  函数的参数与参量也可称为函数的形参实参(形参和实参的概念可以咨询查找学习)
  Python中,函数运行时,其参数和参量实际上会成为local变量,存在于locals中。如下例子:

#!/usr/bin/env python
def foo(x):
print locals()
foo(1)
  结果为:

{'x': 1}
  可以看到,形参x和运行时foo(1)的实参1都成了foo运行时的local变量
  python有许多种定义函数形参和实参的方法,这里我就不具体说了,请参照:
  https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions
  下面我再贴一个例子:

#!/usr/bin/env python
def foo(x, y=0): # 1
return x - y
print foo(3, 1) # 2
print foo(3) # 3
print foo(y=1, x=3) # 4
print foo() # 5
  运行结果:

2
3
2
Traceback (most recent call last):
File "./7.py", line 12, in <module>
print foo() # 5
TypeError: foo() takes at least 1 argument (0 given)
  可以看到#1处定义了x和y两个参数,y给了默认值0.
  在函数调用中,#2,#3,#4都是没有问题的,只有#5报错了。也就是说:
  1. 定义函数参数时,如果没有给某参数设定默认值,则在调用函数时,必须给该参数设定值。
  2. 如果给某参数设定了默认值,则调用函数时,可以给该参数赋值,也可以忽略。
  函数基础大概介绍到这里,关于嵌套函数、闭包等知识,我在另一个博文中介绍:

http://yunjianfei.iteye.com/blog/2186092

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-368881-1-1.html 上篇帖子: Dave Python 练习三 -- 对象 下篇帖子: Python实现线程池
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表