Python基础——函数

函数设计概念

函数设计原则

  • 只有在真正必要的情况下使用全局变量
  • 每一个函数都应该有一个单一的目标:这个目标可以用一个简单说明句来总结,不应该宽泛或者包含多件事情
  • 避免直接改变另一个模块文件中的变量

函数有多种方法获得输入产生输出,一般使用参数作为输入,return语句配合可变参数的改变作为输出。
函数输入

  • 参数
  • 全局变量
  • 文件/流

函数输出

  • return语句
  • 可变参数
  • 全局变量
  • 文件/流

创建

def fun(args):
    return

def语句
def创建了一个函数对象并将其赋值给一个变量。def语句是实时执行的,在模块导入时运行或者在交互模式下输入时运行。
始终记住:函数是一个对象,就像数字、字符串一样。除了函数调用外,还可以dir查看函数对象的属性。

return语句:函数结果作为调用表达式的值,如果没有return语句,函数返回None。

调用

fun()

在函数名后增加()可以调用函数。参数是通过赋值传递的。

lambda表达式:创建一个函数对象并将其作为结果返回。

lambda argu1, argu2, arguN : expression using argus

lambda表达式中可以使用默认参数。
lambda表达式可以实现的函数完全可以用def实现,但是由于lambda是表达式而非语句,可以用在def不适用的地方,比如作为一个列表的元素。另一方面,lambda表达式的主体是个表达式而非代码块,所以只能编写简单函数。示例:

>>>key = 'got'
>>>{'already':(lambda: 2+2), 'got':(lambda: 2*4)}[key]()
8

使用lambda表达式的几种特殊案例:

  • 打印:如果希望在lambda函数中进行打印,应该使用sys.stdout.write()表达式,而不是print语句
  • 选择逻辑:if/else三元表达式lambda x, y : x if x < y else y
  • 循环:如果需要在lambda中执行循环,可以使用map函数或者列表解析表达式
import sys
showall = lambda x:map(sys.stdout.write, x)
t = showall(['spam\n', 'eggs\n'])

showall = lambda x: [sys.stdout.write(line) for line in x]
t = showall(['spam\n', 'eggs\n'])

参数

在调用函数时,需要向函数传递参数。参数的传递是以赋值的形式实现的,遵循赋值操作的约束。
python中关于参数需要着重介绍的概念是参数匹配模型。参数会出现在两个地方:函数头部的参数以及调用时传入的参数,分别称为形参和实参。
函数

  • def fun(name):常规参数:通过位置或者变量名进行匹配
  • def fun(name=value):默认参数
  • def fun(*name):匹配并收集额外不匹配的位置参数到元组name中
  • def fun(**name):匹配并收集额外的不匹配关键字参数到字典name中
  • def fun(*args, name):调用中参数必须按照关键字传递

函数头部参数必须以此顺序出现:一般参数,默认参数,*name,
**name

调用者

  • fun(value):常规参数:通过位置进行匹配
  • fun(name=value):关键字参数:通过变量名进行匹配
  • fun(*seq):解包序列成一般参数,按位置传递所有参数
  • fun(**dict):解包字典成关键字参数,按关键字传递所有参数

函数调用中,参数必须以此顺序出现:位置参数,关键字参数,*seq,
**dict

参数匹配步骤

  • 通过位置匹配非关键字参数
  • 通过变量名匹配关键字参数
  • 额外的非关键字参数收集到*name元组中
  • 额外的关键字参数收集到**name字典中
  • 对于在头部未得到分配的参数使用默认值

当所有的匹配都完成后,通过赋值操作实现传参。

变量的作用域

本地变量:在def内的函数中是可见的,并且仅在函数调用时存在,在函数退出时消失。
global:声明模块级的变量

递归函数

对于线性迭代,一般使用循环结构而不用递归,因为前者简单并且高效;但是对于需要遍历任意形状结构的情况,循环不再适用,这个时候需要使用递归。

其他

生成器函数
yield表达式替代常规函数中的return语句,用于定义生成器函数,调用时返回一个迭代器对象,该对象支持next()方法,可以开始这个函数或者从上次yield值后的地方恢复。
以常规的def语句编写,但是使用yield语句一次返回一个结果。这样仅在需要的时候才产生结果,而不是立即产生所有结果。

def gensquares(N):
    for i in range(N):
        yiled i ** 2
x = gensquares(4)
next(x)-->0
next(x)-->1
next(x)-->4
next(x)-->9
next(x)-->StopIteration

生成器在内存使用和性能方面都比常规函数更好,尤其在结果列表很大时,这一点尤其有用。
生成器表达式
和列表解析式非常类似,区别在于用()而非[]括起来。生成器表达式返回一个生成器对象,支持迭代协议,可以使用所有的迭代工具。
生成器本身就是迭代器,和文件对象相同。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值