python—函数

函数

定义和注意事项

  1. 将可能需要反复执行的代码封装为函数,并在需要该功能的地方进行调用,不仅可以实现代码复用,更重要的是可以保证代码的一致性,只需要修改该函数代码则所有调用均受到影响。
  2. 设计函数时,应注意提高模块的内聚性,同时降低模块之间的隐式耦合。
  3. 在实际项目开发中,往往会把一些通用的函数封装到一个模块中,并把这个通用模块文件放到顶层文件夹中,这样更方便管理。
  4. 在编写函数时,应尽量减少副作用,尽量不要修改参数本身,不要修改除返回值以外的其他内容。
  5. 应充分利用Python函数式编程的特点,让自己定义的函数尽量符合纯函数式编程的要求,例如保证线程安全、可以并行运行等等。
  6. 函数定义时括弧内为形参,一个函数可以没有形参,但是括弧必须要有,表示该函数不接受参数。
  7. 函数调用时向其传递实参,将实参传递给形参。
  8. 在定义函数时,对参数个数并没有限制,如果有多个形参,需要使用逗号进行分隔。
  9. 对于绝大多数情况下,在函数内部直接修改形参的值不会影响实参,而是包建一个新变量。

函数定义语法:

def 函数名([参数列表]):
    函数体

注意:

  • 函数形参不需要声明类型,也不需要指定函数返回值类型
  • 即使该函数不需要接收任何参数,也必须保留一对空的圆括号
  • 括号后面的冒号必不可少
  • 函数体相对于def关键字必须保持一定的空格缩进
  • Python允许嵌套定义函数
总之,函数可以改变参数的值,进行传递,并不会是局部变量
  • 在Python中,函数参数有很多种:可以为普通位置参数、默认值参数、关键参数、可变长度参数等等。
  • Python在定义函数时不需要指定形参的类型,完全由调用者传递的实参类型以及Python解释器的理解和推断来决定。
  • 不需要指定函数的返回值类型,函数的返回值类型由return语句返回值的类型决定。如果函数没有return语句,或者没有执行到return语句,或者执行了不带任何值的return语句,则函数都默认返回空值None。
  • 调用函数的实参和形参的位置必须一样,数量也必须相同。
  • 在设置默认值参数的时候,两个默认值参数中间不能加非默认值参数
____defaults____可以查看函数的默认值参数的当前值,并且返回一个元组,其顺序按照当时值进行传递
def test(a,b=2,c=5):
 print(a,b,c)
print(test.__defaults__)
多次调用函数并且不为默认值参数传递值时,默认值参数只在定义时进行一次解释和初始化,对于列表、字典这样可变类型的默认值参数,这一点可能会导致很严重的逻辑错误。
def test(new,old=[]):
    old.append(new)
    return old
print(test(1,[1,2,3,4]))
print(test(1))
print(test(2))

[1, 2, 3, 4, 1]
[1]
[1, 2]
函数的默认值参数是在函数定义时确定值的,只会被初始化一次。
i=3
def test(n=i):
    print(n)
test()
i=2
test()
i=56
test(2)

3
3
2
按照参数名字传参
  • 按参数名字传递值,明确指定哪个值传递给哪个参数。
  • 通过关键参数,实参顺序可以和形参顺序不一致,但不影响传递结果,避免了用户需要牢记位置参数顺序的麻烦,使得函数的调用和参数传递更加灵活方便。
  • 关键参数主要指调用函数时的参数传递方式,与函数定义无关。
可变长度参数
  • *parameter用来接受多个实参并将其放在一个元组中
  • **parameter接受多个关键参数并存放到字典中
def test1(*p):
     print(p)
def test2(**p):
     print(p)
if __name__=="__main__":
     test1(1,2,3,4)
     test2(x=1,y=2,z=3)
    
(1, 2, 3, 4)
{'x': 1, 'y': 2, 'z': 3}
参数传递的序列解包

调用函数时对实参序列使用一个星号*进行解包后的实参将会被当做普通位置参数对待,并且会在关键参数和使用两个星号**进行序列解包的参数之前进行处理。

def demo(a,b,c):
   print(a+b+c)
seq=[1,2,3]
sxe=(1,2,3)
demo(*seq)
demo(*sxe)

6
6

解包字典

def demo(a,b,c):
 print(a+b+c)
seq=['a','b','c']
sxe=(1,2,3)
demo(**dict(zip(seq,sxe)))
6

序列解包相当于位置参数,优先处理

demo(a,b,c)
demo(a=1,*(1,2))#错误
demo(b=1,*(1,2))#错误
demo(c=1,*(1,2))#正确

序列解包在关键参数解包之后

demo(**{'a':1,'b':2}, *(3,))#错误
demo(*(3,),**{'a':1,'b':2} )#错误
demo(**{'c':1,'b':2},*(3,))#错误
demo(*(3,),**{'c':1,'b':2} )#正确
return

return语句用来从一个函数中返回一个值,同时结束函数。无论出现在函数的什么位置,一旦执行结束函数。
对于以下情况,Python将认为该函数以return None结束,返回空值:

  • 函数没有return语句;
  • 函数有return语句但是没有执行到;
  • 函数有return但是没有返回任何值。

变量

定义
  1. 变量起作用的代码范围称为变量的作用域,不同作用域内变量名可以相同,互不影响。
  2. 在函数内部定义的普通变量只在函数内部起作用,称为局部变量。当函数执行结束后,局部变量自动删除,不再可以使用。
  3. 局部变量的引用比全局变量速度快,应优先考虑使用。
  4. 除了在函数内部定义变量,Python还允许在所有函数的外部定义变量,这样的变量称为全局变量(Global Variable)。
  5. 和局部变量不同,全局变量的默认作用域是整个程序,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用。
  6. 如果在函数内任意位置有为变量赋新值的操作,该变量即被认为是(隐式的)局部变量,除非在函数内显式地用关键字global进行声明。
  7. 如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内隐藏同名的全局变量。
  8. 一个变量已在函数外定义,如果在函数内需要为这个变量赋值,并要将这个赋值结果反映到函数外,可以在函数内使用global将其声明为全局变量。
  9. 如果一个变量在函数外没有定义,在函数内部也可以直接将一个变量定义为全局变量,该函数执行后,将增加一个新的全局变量。
变量作用域的实操重点

如果需要在同一个程序的不同模块之间共享全局变量的话,可以编写一个专门的模块来实现这一目的。例如,假设在模块A.py中有如下变量定义:

a=1

B.py中包含以下来设置全局变量

import A
A.a=2

C.py 中有以下语句来访问全局变量

import A
print(A.a)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值