Python3 函数相关知识

目录

定义一个函数

语法

实例

函数参数 

必须参数

关键字参数

默认参数

不定长参数(收集参数、可变参数)

 匿名函数

python 使用 lambda 来创建匿名函数

变量作用域

全局变量和局部变量

global 和 nonlocal关键字

函数嵌套

 函数的高级话题

filter函数:筛选

map函数(序列中的映射函数)


函数是封装好的,可以重复使用,能提高应用的模块性和代码的重复利用率。Python提供了许多内建函数,比如print()。但也可以自己创建函数,这被叫做用户自定义函数。

定义一个函数

规则:

  • 函数代码块以def关键词开头,后接函数标识符名称和圆括号()。
  • 传入参数和自变量必须放在圆括号内,圆括号里还可以定义参数。
  • 函数体里可以存放函数说明。
  • 函数内容以冒号开始,自带缩进。
  • return[表达式]结束函数,返回一个值给调用方。不带表达式的return相当于返回none。
  • ruturn 多个结果,如:return x,y,z..

语法

Python 定义函数使用 def 关键字,一般格式如下:

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

默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配的。

实例

#def定义一个函数
def MyFirstFunction():
    print('迈出第一步')
    print('成功在等着你')
    print('不放弃')

#调用函数
MyFirstFunction()

运行结果:

迈出第一步
成功在等着你
不放弃

写一个带参数的函数:

def add(num1,num2):
    return(num1+num2)

print(add(5,6))
    

运行结果:

11

函数参数 

形参(parameter)和实参 (argument):上述中的num1和num2叫作形参(只占据一个位置),5,和4叫作实参(具体的参数值)

以下是调用函数时使用的参数类型:

  • 必须参数
  • 关键字参数
  • 默认参数
  • 不定长参数(收集参数、可变参数)

必须参数

必需参数必须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

调用printme()函数,你必须传入一个参数,不然会出现语法错误:

#可写函数说明
def printme( str ):
   "打印传入的字符串"
   print (str)
   return
 
#调用printme函数
printme()

以上实例输出结果:

raceback (most recent call last):
  File "test.py", line 10, in <module>
    printme()
TypeError: printme() missing 1 required positional argument: 'str'

关键字参数

使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

以下实例在调用函数时不再担心参数顺序导致出错:

def SaySome(name,words):
    print(name+'->'+words)
    
SaySome('小白','加油')

SaySome('加油','小白')

SaySome(words='加油',name='小白')

以上实例运行结果:

小白->加油
加油->小白
小白->加油

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

def printinfo( name, age = 35 ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )

以上实例输出结果:

名字:  runoob
年龄:  50
------------------------
名字:  runoob
年龄:  35

不定长参数(收集参数、可变参数)

当你不知道需要多少参数时(在参数前加*)就能解决。这些参数叫做不定长参数。

实例:

def test(*params):
    print('参数长度是:',len(params));
    print('第二个参数是:',params[1]);
    
test(1,'小鱼',3.14,5,6,7,8)

运行结果:

参数长度是: 7
第二个参数是: 小鱼

注意:如果还存在除不定长参数以外的其他参数,必须在调用函数时将值赋给形参,否则将自动把所有参数给不定长参数。

另外一种情况:

#如果不赋值exp=8,将自动将所有参数给*params
def test(*params,exp):
    print('参数长度是:',len(params));
    print('第二个参数是:',params[1]);
    
test(1,'小鱼',3.14,5,6,7,exp=8)

运行结果:

参数长度是: 6
第二个参数是: 小鱼

还有一种就是参数带两个星号 **基本语法如下:

def functionname([formal_args,] **var_args_dict ):
   "函数_文档字符串"
   function_suite
   return [expression]

加了两个星号 ** 的参数会以字典的形式导入。

实例:

def printinfo( arg1, **vardict ):
   print ("输出: ")
   print (arg1)
   print (vardict)
 
# 调用printinfo 函数
printinfo(1, a=2,b=3)

以上实例输出结果:

输出: 
1
{'a': 2, 'b': 3}

声明函数时,参数中星号 * 可以单独出现,例如:

def f(a,b,*,c):
    return a+b+c

如果单独出现星号 * 后的参数必须用关键字传入。

>>> def f(a,b,*,c):
...     return a+b+c
... 
>>> f(1,2,3)   # 报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given

>>> f(1,2,c=3) # 正常
6
>>>

加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。 例如:

def greetPerson(*name):
    print('Hello', name)
  
greetPerson('Runoob', 'Google')

输出结果:

Hello ('Runoob', 'Google')

 匿名函数

python 使用 lambda 来创建匿名函数

所谓匿名,即不再使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

lambda 函数的语法只包含一个语句,如下:

lambda [arg1 [,arg2,.....argn]]:expression

如下实例:

>>> g=lambda x:2*x+1
>>> g(5)
11

变量作用域

Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:

  • L (Local) 局部作用域
  • E (Enclosing) 闭包函数外的函数中
  • G (Global) 全局作用域
  • B (Built-in) 内置作用域(内置函数所在模块的范围)

以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

g_count = 0  # 全局作用域
def outer():
    o_count = 1  # 闭包函数外的函数中
    def inner():
        i_count = 2  # 局部作用域

内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:

>>> import builtins
>>> dir(builtins)

Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:

>>> if True:
...  msg = 'I am from Runoob'
... 
>>> msg
'I am from Runoob'
>>> 

实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。

如果将 msg 定义在函数中,则它就是局部变量,外部不能访问:

>>> def test():
...     msg_inner = 'I am from Runoob'
... 
>>> msg_inner
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'msg_inner' is not defined
>>> 

从报错的信息上看,说明了 msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。

全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

total = 0 # 这是一个全局变量

def sum( arg1, arg2 ):
 
    total = arg1 + arg2 # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)
    return total
 
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)

以上实例输出结果:

函数内是局部变量 :  30
函数外是全局变量 :  0

global 和 nonlocal关键字

当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。

global 关键字修改全局变量 (在全局变量前加global即可以修改)

count=5
def MyFun():
    global count
    count=10
    print(10)
    
MyFun()

以上实例输出结果:

10

nonlocal关键字修改局部变量与(global相似),强调参数不是局部变量

def Fun1():
    x=5
    def Fun2():
        nonlocal x  #强制声明x不是局部变量
        x *=x
        return x
    return Fun2()

Fun1 ()   #调用Fun1  

以上实例输出结果:

25

函数嵌套

如下实例:

注意 :只能在fun1()里面调用fun2()不能在外部调用内部函数

 函数的高级话题

filter函数:筛选

filter(None或函数,可迭代序列)

 当默认为None时,筛选掉非True。如下:

>>> filter(None,[1,0,False,True])
<filter object at 0x03800470>
>>> list(filter(None,[1,0,False,True]))
[1, True]

下面实例:筛选奇数

>>> list(filter(lambda x:x%2,range(10)))
[1, 3, 5, 7, 9]

map函数(序列中的映射函数)

内置高阶函数,它接收一个函数 f 和一个list,并把函数 f 依次作用在list的每个元素上,得到一个新的list并返回。

map(None或函数,可迭代序列)

 如下实例:函数将会为range(10)列表中的每一个元素平方。

>>> list(map(lambda  x:x*2,range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值