讲解python参数和作用域的使用


Posted in Python onNovember 01, 2013

本文会介绍如何将语句组织成函数,还会详细介绍参数和作用域的概念,以及递归的概念及其在程序中的用途。
一. 创建函数
函数是可以调用,它执行某种行为并且返回一个值。用def语句即可定义一个函数:(并非所有的函数都会返回一些东西)

def fibs(num):
    result = [0,1]
    for i in range(num-2):
        result.append(result[-2]+result[-1])
    return result

记录函数
如果想给函数写文档以便让人理解的话,可以加入注释(以#开头)。另一个方式就是直接写上字符串,它会作为函数的一部分进行存储,这成为文档字符串。
def square(x):
    '计算x的平方'
    return x*x

#文档字符串可以按如下方式访问:
>>> square._doc_
'计算x的平方'

二. 参数魔法
函数使用起来很简单,创建起来也不复杂,但是函数参数的用法有时就不可思议了。
2.1 我能改变参数吗
 在函数内为参数赋予新值,不会改变外部任何变量的值:

>>> def to_change(n):
    n = 's'
>>> name = 'b'
>>> to_change(name)
>>> name
'b'

字符串(以及数字和元组)是不可变的,即无法被修改。但是如果将可变的数据结构如列表用作参数时,参数就会被改变了。
>>> def change(n):
    n[0] = 'ss'
>>> names = ['aa','zz']
>>> change(names)
>>> names
['ss', 'zz']

2.2 关键字参数和默认值
目前为止,我们所使用的参数都叫做位置参数。有时候参数顺序是很难记住的,为了让事情简单些,可以提供参数的名字:

>>> def hello(greeting,name):
        print '%s,%name!'
>>> hello(greeting = 'hello',name = 'world')
hello,world!

这样一来,参数顺序就完全没影响了,但是参数名和值一定要对应。
这样使用参数名提供的参数叫做关键字参数,主要作用在于可以明确每个参数的作用。
关键字参数最厉害的地方在于可以在函数中给参数提供默认值:
>>> def hello(greeting = 'hello',name = 'world'):
        print '%s,%name!'
当参数具有默认值时,调用的时候就不用提供参数了,可以不提供,提供一些或提供所有的参数。
>>> hello()
'hello,world!'
>>> hello('greeting')
'greeting,world!'
>>> hello(name = 'universe')
'hello,universe!'
 

2.3 收集参数
如果函数中能存储多个名字就好了,用户可以给函数提供任意多的参数,我们需要这样做:定义函数时提供一个参数,在前面加个星号。
>>> def print_para(*paras):
    print paras
>>> print_para('ss')
('ss',)
>>> print_para(1,2,3)
(1, 2, 3)

参数前的星号将所有值放置在同一个元组中,可以说是将这些“其余位置的参数”收集起来再使用。如果不提供任何收集元素,参数得到的是一个空元组()。
但是如果需要处理关键字参数的“收集”操作,我们需要2个星号“**”:
>>> def print_params(x,y,z=3,*pospar,**keypar):
    print x,y,z
    print pospar
    print keypar>>> print_params(1,2,3,5,6,7,foo=1,bar=2)
1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}
>>> print_params(1,2)
1 2 3
()
{}

请仔细体味上面的例子,前三个参数是固定的,第四个参数pospar是位置参数,可以收集多个参数,第五个参数是关键字参数,可以收集多个关键字参数。当没有输入时,默认为空元组或者空字典。

2.4 反转过程
刚刚已经讨论过如何将参数收集为元组和字典了,如果使用*和**的话,还可以执行相反的操作。(1)在调用的时候使用

>>> def add(x,y):
    return x+y
>>> params =(1,2)
>>> add(*params)
3

(2)在定义的时候使用
>>> def with_stars(**kds):
    print kds['name'],'is',kds['age'],'years old'
>>> args = {'name':'Mr.Gumby','age':42}    
>>> with_stars(**args)
Mr.Gumby is 42 years old
 

三. 作用域
在执行x=1赋值语句后,名称x引用到值1。这就像用字典一样,键引用值,当然,变量和所对应的值用的是个‘不可见'的字典。内建vars函数可以返回这个字典:
>>> x=1
>>> scope = vars()
>>> scope['x']
1
>>> scope['x'] += 1
>>> x
2

这个不可见的字典叫做命名空间或者作用域。除了全局作用域外,每个函数调用都会创建一个新的作用域。
一般学过编程的基本都知道什么是作用域了,这里就不细讲了。

四. 递归
递归的定义包括它们自身定义内容的引用。
一个有用的递归函数包含以下几部分:
(1)当函数直接返回值时有基本实例(最小可能性问题)
(2)递归实例,包括一个或者多个问题最小部分的递归调用。
这里的关键是将问题分解为小部分,递归不能永远继续下去,因为它总是以最小可能性问题结束,而这些问题又存储在基本实例中。
下面我们来看3个经典的递归例子:
A.阶乘
>>> def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)
[/code]
B.幂

>>> def power(x,n):
    if n == 0:
        return 1
    else:
        return x * power(x,n-1)

C.二元查找(假设number必然在序列sequence中)
>>> def search(sequence,number,lower,upper):
    if lower == upper:
        assert num == sequence[upper]
        return upper
    else:
        middle = (lower+upper) // 2
        if number > sequence[middle]:
            return search(sequence,number,middle+1,upper)
        else:
            return search(sequence,number,lower,middle)
Python 相关文章推荐
Python中使用scapy模拟数据包实现arp攻击、dns放大攻击例子
Oct 23 Python
Python简单日志处理类分享
Feb 14 Python
pygame学习笔记(5):游戏精灵
Apr 15 Python
讲解Python中for循环下的索引变量的作用域
Apr 15 Python
Python获取linux主机ip的简单实现方法
Apr 18 Python
fastcgi文件读取漏洞之python扫描脚本
Apr 23 Python
Python中关于Sequence切片的下标问题详解
Jun 15 Python
python 判断是否为正小数和正整数的实例
Jul 23 Python
python解决字符串倒序输出的问题
Jun 25 Python
浅析python3字符串格式化format()函数的简单用法
Dec 07 Python
python numpy 按行归一化的实例
Jan 21 Python
在Python中构建增广矩阵的实现方法
Jul 01 Python
python列表与元组详解实例
Nov 01 #Python
python创建和使用字典实例详解
Nov 01 #Python
python分割和拼接字符串
Nov 01 #Python
python list语法学习(带例子)
Nov 01 #Python
python读取Android permission文件
Nov 01 #Python
Python读写Excel文件的实例
Nov 01 #Python
Python修改Excel数据的实例代码
Nov 01 #Python
You might like
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
ThinkPHP打水印及设置水印位置的方法
2016/10/14 PHP
php微信公众号开发之校园图书馆
2018/10/20 PHP
php如何利用pecl安装mongodb扩展详解
2019/01/09 PHP
javascript事件模型代码
2007/07/01 Javascript
Jquery 基础学习笔记之文档处理
2009/05/29 Javascript
jquery不会自动回收xmlHttpRequest对象 导致了内存溢出
2012/06/18 Javascript
js中的如何定位固定层的位置
2014/06/15 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
2016/07/05 Javascript
jQuery实现淡入淡出的模态框
2017/02/09 Javascript
js实现鼠标拖动功能
2017/03/20 Javascript
详解Webpack+Babel+React开发环境的搭建的方法步骤
2018/01/09 Javascript
使用vue制作探探滑动堆叠组件的实例代码
2018/03/07 Javascript
基于webpack4+vue-cli3项目实现换肤功能
2019/07/17 Javascript
Vue的data、computed、watch源码浅谈
2020/04/04 Javascript
Python深入学习之闭包
2014/08/31 Python
Python字符串格式化
2015/06/15 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
python3中dict(字典)的使用方法示例
2017/03/22 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
使用PyInstaller将python转成可执行文件exe笔记
2018/05/26 Python
Python面向对象程序设计之静态方法、类方法、属性方法原理与用法分析
2020/03/23 Python
pycharm中leetcode插件使用图文详解
2020/12/07 Python
澳大利亚领先的武术用品和健身器材供应商:SMAI
2019/03/24 全球购物
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
法国在线药房:Shop Pharmacie
2019/11/26 全球购物
"引用"与多态的关系
2013/02/01 面试题
高校毕业生登记表自我鉴定
2013/11/03 职场文书
大学生优秀自荐信范文
2014/02/25 职场文书
社区食品安全实施方案
2014/03/28 职场文书
担保书格式
2015/01/20 职场文书
入伍通知书
2015/04/23 职场文书
2015年学校安全管理工作总结
2015/05/11 职场文书
小学数学新课改心得体会
2016/01/22 职场文书
《窃读记》教学反思
2016/02/18 职场文书
《艾尔登法环》Boss腐烂树灵很有可能是《黑暗之魂3》的一个废案
2022/04/11 其他游戏