[python3教程]第四章.定义函数

4.6定义函数

        我们可以定义一个函数,用来计算Fibonacci:


这里注意关键字def,函数都是使用def来定义的,后面是函数名括号里是要传给函数的参数。同时别忘记输冒号,在另起一行缩进一个制表符后开始写函数的内容。一般来说我们应该在第一行加上对函数的说明,这是个利人利己的大好事,最好养成这个习惯。接下来我们说一下定义域,我们定义fib(n),其中这个n在C语言中我们叫做形参,在这个函数中n,a,b,这三个变量的定义域都是在函数内,也就是说只在函数内好用,无法在函数外调用它们,一旦函数运行完毕他们占用的内存就会被释放所以无法继续调用。那在函数内是否可以调用函数外的变量那?函数内的调用首先会在函数自己的变量中查找,如果查找不到再去全局变量里搜索,也就是说如果函数内有一个变量名和全局变量同名,那么函数就不会使用全局变量。如果全局变量里也没有,最后会去python内建的变量中搜索。同时将实参传递给函数后,函数的定义域的内会增加其对应的形参。也就是说不能通过修改形参的方法去修改实参。

        函数的名称也是一种变量,这种类型的变量被存在当前的定义域里。因为python不用定义变量类型(这点挺方便的,但有的时候也要进行类型转换),所以我们能直接把函数名分配给一个新变量。

有些同学认为这个fib函数不能叫函数,因为他没有返回值。事实上函数里即使不写return也是肯定会返回一个值,在python中这个值叫做None注意python是对大小写敏感的哦~一般情况None是被解释器抹掉的,可以用print函数打印出来:。下面我们用函数返回一个list看看:

由上图能看出来,函数时可以(一定)会返回一个对象的,如果没有函数本身没有要求返回值他就会默认返回一个None。result.append(a)调用了一个实例方法,就是list类的append方法,可以把这种方法理解为类的天赋,各种类都有各自的能力(就是在定义类的时候写在里面的)。不同的类用同样的方法名并不会冲突的。

4.7关于定义函数的更多

4.7.1默认形参

        设置默认形参是一种很常见的情况,这种方式可以在使用的时候传入参数少于定义的形参数(但其实他只是使用了默认值,并非不需要给形参赋值)。举个栗子:


这个函数我们就可以只传一个提示符(prompt):ask_ok('Do you really want to quit?')

还可以设置输入的次数:ask_ok('你真的想这么做?', 2)这样我们会用2替代retries默认设置的4

或者将所有的形参都设置一遍:ask_ok('你确定你真的想好了?’, 2, '告诉我好不好就行了!')

由此可见给自己定义的结构写说明有多么的重要啊,能让别人更好的使用你定义出来的东西,同时这个例子里面咱们还用到了in他可以检测一个值是否被包含在序列内。有一点需要咱们注意一下:

上面这个例子最后打印出来的是5,因为我们的形参会自动把i的值当作默认值,而不是保留一个变量作为自己的默认值。

注意注意!默认的形参值只赋值一遍,但如果形参本身就是一个可变的类型(list,dictionary,etc..)那就会有点不同。举个会把形参不断改变的例子:

我们可以看到  l 这个list被不断地累加,并没有每次都恢复我们设置的默认为空。说实话我并不喜欢这个设计,这容易让人误以为在函数内定义的list可以全局使用,而事实上是不可以的。所以最好定义一个if结构来判断一下是否是我们想要的默认值。

4.7.2关键字

        在传递参数的时候可以直接将形参的名字写出来,栗子:

这个鹦鹉只有电压是必须输入的参数其他三个都有默认值,下面我们看看我们要学习的性特性:

parrot(1000)这个一点问题也没有,直接给voltage赋值。

parrot(voltage=1000)这和上面的例子本质上是一样的,就是把形参的关键字写出来了直接赋值。

parrot(voltage=1000,action='voooom')这个例子体现出关键字的用处,我们跳过了state直接给action赋值。

parrot(action='voooom', voltage='10000')有了关键字,赋值的顺序就可以随心所欲了~

parrot('a thousand', state='pushing up the daisies')前面用的是位置,后面用关键字赋值,但注意!!!!用了关键字之后就不能使用位置了,因为使用了关键字顺序就乱了,并不能明白到底是给谁赋值。

接下来我们介绍一个有意思的东西*(asterisk),一个*表示这个形参能接收多个变量(会被保存成一个元组),两个*不但接受了多个变量同时还接受了多个形参名,传入的变成了一个字典。这个是比较常用的哦,举个栗子:

我们可以清楚的看到a被形参kind接受了,后面的b和c被arguments作为元组接受了,而def和对应的no1,no2,no3被keywords作为字典接受了。注意一下这里对keywords进行了排序生成了一个list这个list里面就是[no1,no2,no3],书中原文是这么写的,但是我更倾向于直接:

for k in kewords:

    print(k, ':', keywords[k])

这样就不需要在返回那个list最后的结果都是一样的。

4.7.3打包传入形参

        通过上面的例子我们知道可以将形参设置为list或者字典,然后在传入参数的时候就会自动到对应的形参中,同时我们也可以直接将一个list传入赋值给多个形参;举个简单的例子range()函数要传入起始和结束,我们其实可以直接把一个list传入给他,只需要释放出这个list就可以了:

同样我们可以把一个字典传入,只要字典里面索引名和形参名字一致就可以:


在这个例子里我们就把所有的形参用一个字典传入了,其实这个方法和上一小节是一样的只是一个是传入字典,一个是形参本身就是字典。

4.7.5lambda表达式

         lambda表达式的作用就是快速的生成一些小函数,比如lambda x,y : x + y这个lambda表达式会返回一个函数用来计算两个数的和,在语法上是和一般的表达式并无二致的,说白了就是一个语法糖让我们用起来更舒服。我们来举个实际点的栗子:

其实我第一看到这部分的时候也没看明白,这大兄弟是几个意思啊,后来琢磨琢磨其实也就是那么回事。return lambda的时候返回给f的是一个函数,也就是说f这个变量存的其实是一个函数,在lambda表达式中我们冒号左边定义的是形参,可以看到这个表达式形参只有一个x,所有使用这个函数的时候只需要导入一个参数就够了。我们再看一个栗子:

在这个例子中我们用lambda表达式直接作为一个函数传递给了形参,是不是很方便~~~

4.7.6文档说明(Documentation Strings)

        对于说明的内容和格式我们做了一些约定,在第一行我们要简要明朗的把这个函数的作用写出来。为了简洁我们并不会把所有的对象都写出来。别忘了首字母大写然后末尾加上一个句号.(英文版的)。如果我们要写多行的说明的话第二行空白就是啥都不要写,为的是在视觉上能把总结部分和余下部分分开。剩下的部分我们可以化为几个段落介绍调用方法之类的东东。当然我没参与过实际的编码工作,所以不知道是否有哪些组织使用中文作为函数说明。栗子·:

.

关于函数注释这部分我不太想写了,感觉好像有点没啥用啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值