Python函数

Posted 礁之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python函数相关的知识,希望对你有一定的参考价值。

文章目录


此文章参考廖雪峰大神的官方:调用函数 - 廖雪峰的官方网站 (liaoxuefeng.com)

一、什么是函数

  • 函数通俗的来讲,就是一段固定的代码,函数还可以传入参数,最终得到的结果其实就固定代码的执行结果。
  • python中内置了许多函数,我们可以直接进行调用,并且我们自己也可以自定义函数

二、调用函数

  • python内置了许多函数,我们可以直接进行调用
  • 如果要调用函数的话,需要先知道函数的函数名称以及可以传入参数的数量和数据类型等,可以去pyton的官网进行查询:查询python内置函数
  • 也可以在python交互模式中使用help()函数来查看指定函数的相关信息
>>> help(abs) 
Help on built-in function abs in module builtins:

abs(x, /)
    Return the absolute value of the argument.
  • 调用函数时,如果传入的参数数量、数据类型不对的话,会报错,以求绝对值函数abs()为例:
>>> abs(1,2,3) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (3 given)
>>> abs(1)     
1
>>> abs("1") 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'
        
#例如求最大值函数max这种函数,可传入的参数数量就和abs不同
>>> max(1,23,4,5) 
23
  • 除了上述的max和abs,python内置的常用函数还包括数据类型转换的函数,下面来看几个例子:
>>> int('123')   #转换字符串为数字
123
>>> int(12.33)  #转换浮点数为整数
12
>>> str(123)  #转换数字为字符串
'123'
>>> bool(1)  #转换数字为布尔值
True
>>> list('aaa')  #转换字符串为列表
['a', 'a', 'a']
  • 函数还可以指向其他变量:
>>> a = abs  
>>> a(-1) 
1
>>> abs(-1) 
1

三、定义函数

  • 定义函数可以使用def语句,依次写出def 函数名(参数):,输入回车,在缩进块中编写代码,函数的返回值使用return语句返回
  • 以一个计算数字平方的函数示例:
- 交互环境中:
>>> def test(x):   #输入:后会有...提示符,输入代码后连续两次回车可以返回>>>提示符下
...     return x * x 
... 
>>> test(2) 
4
>>> test(22) 
484

- 写入py文件中:
# -*- coding: utf-8 -*-
def test(x):
    return x * x 

print(test(2))
print(test(22))

#输出
4
484
  • 要注意的是,在函数中的语句执行时,只要遇到了return语句时,就代表函数执行完毕,并且返回执行结果,如果一个函数中没有return语句,函数也会返回值,但是这个值是Nonereturn没有指定返回值也会返回None,也就是说return None可以写成return

  • 如果想要定义的函数什么都不做,可以使用pass语句:

>>> def test(x):
...     if x > 10:
...             return x
...     else:
...             pass
... 
>>> test(20)      
20
>>> test(9)  
>>> 

#pass语句表示什么都不做,可以作为占位符,例如函数的代码还没想好怎么写,就可以
  • 如果还想让函数返回多个值的话,可以这样做:
# -*- coding: utf-8 -*-
def test(i):
    x = i + 1
    y = i - 1
    return x,y
print(test(20))    

#输出:
(21, 19)

四、函数的参数

  • 在定义函数的时候,我们需要把函数参数的名字、数量、位置确定下来,在确定下来之后,函数的接口其实也就定义完成
  • 对于函数调用者来说,想要使用函数只需要知道如何传递正确的参数、参数的数量、参数的类型等,以及调用函数后会返回什么值,这样就已经足够了,而函数中间的逻辑算法等,调用者是不用去了解的
  • Python函数的定义简单、灵活度大,除了正常定义的必选参数外,还可以使用默认参数可变参数关键字参数,使得函数定义出来的接口,不但能够处理复杂的参数,还可以简化调用者的代码

1、位置参数

1、我们先来定义一个计算x二次方的函数:
>>> def test(x):
...     return x * x
... 

在test函数中,变量x就是位置参数,当我们要调用test函数时,必须传入x参数,并且只能传输一个,下面来看调用test参数时传入不同参数时的输出的结果
>>> print(test(4))   #传入整数
16
>>> print(test(4.5))   #传入浮点数
20.25
>>> print(test('4'))   #传入字符串,发现报错了,因为字符串无法使用 “ * ” 进行运算
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
TypeError: can't multiply sequence by non-int of type 'str'
>>> print(test(4,5))   #传入两个参数,同样报错,因为test函数中只有一个位置参数
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes 1 positional argument but 2 were given
>>> print(test())      #不传入任何参数,因为test函数中必须传入一个参数x,所以报错了
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() missing 1 required positional argument: 'x'

2、现在来优化test参数,使之可以计算x的n次方:
>>> def test(x,n):
...     i = 1
...     while n > 0:
...             n = n -1 
...             i = i * x 
...     return i 
... 
>>> print(test(7,3)) 
343

在优化后的test函数中,多了一个参数n,那么在每次调用test函数时,就需要两个数字类型的参数,传入的参数按照x和n的前后顺序依次传入,例如test(7,3),则x=7,n=3

2、默认参数、

  • 从上面说的位置参数来看,我们可以知道在调用函数时传入参数的数量数据类型都必须正确,否则会报错。
  • 以优化后可以计算x的n次方函数test为例,如果我们需要多次调用test函数,而每次参数n的值都是2时,我们需要每次调用函数都传入两个参数,这样调用的话,我们会传入很多重复的参数,而默认参数就可以帮助我们减少重复操作
1、定义test函数,可以计算x的n次方,默认计算是x的2次方
>>> def test(x,n=2):       
...     i = 1
...     while n > 0:
...             n = n - 1
...             i = i * x
...     return i
... 
>>> print(test(3,2)) 
9
>>> print(test(3))   
9
从调用test函数可以看出,默认n的参数没有传入时,n=2

2、在使用默认参数时,默认参数必须要指向不变对象,即不可变类型,下面来看一个案例:
>>> def aaa(L=[]):
...     L.append('end')
...     return L
... 
>>> print(aaa([1,2,3]))
[1, 2, 3, 'end']
>>> print(aaa(['x','y','a'])) 
['x', 'y', 'a', 'end']
>>> print(aaa())              
['end']
>>> print(aaa())
['end', 'end']
>>> print(aaa([1,2,3])) 
[1, 2, 3, 'end']
从上面的案例可以看出,在定义aaa参数时使用了L=[ ]作为默认参数,在我们正常调用aaa函数,传入列表参数时,输出的结果都是正常的,而在没有传入参数,使用aaa函数的默认参数时,我们发现在调用两次后,输出的结果并不是我们想的一个end,而是又添加了一个end,这是因为在定义函数时,默认参数L的值就已经被计算出来了,因为L也算一个变量,它指向了对象[ ],在每次调用时,如果修改了L的内容(即修改了空列表[ ]),则在下次调用时,L会变成修改后的值(即修改后的列表['end']),所以会输出这种结果

而解决的方法其实可以加一个if判断例如:
>>> def aaa(L=None):
...     if L is None:
...             L = [] 
...     L.append('end')
...     return L
... 
>>> print(aaa()) 
['end']
>>> print(aaa())
['end']
>>> print(aaa([1,2,3])) 
[1, 2, 3, 'end']
定义L的默认值为None,当L等于None时,才会定义一个空列表,这样就可以避免上面的情况

在定义默认参数时需要注意:

  1. 函数的参数传入是通过前后顺序,所以在定义默认参数时,要把必选参数放在前面,默认参数放在后面,否则会造成必须参数的值错误的传入了默认参数,而必须参数没有传入值,从而报错
  2. 默认参数必须指向不可变类型,避免不必要的错误

3、可变参数

  • 在python中,还可以定义可变参数
1、定义一个函数test,当传入的函数为a,b,c时,test函数可以计算a*a+b*b+c*c
>>> def test(number):
...     sum = 0
...     for i in number:
...             sum = sum + i * i
...     return sum
... 
>>> print(test([1,2,3,4])) 
30
>>> print(test((7,3,15,4)))  
299

上面定义的test函数虽然可以达到效果,但是在每次调用函数时,传入的参数需要先组装成一个列表或者元组

2、使用可变参数优化后:
>>> def test(*number):
...     sum = 0
...     for i in number:
...             sum = sum + i * i
...     return sum
... 
>>> print(test(1,2,3,4)) 
30
>>> print(test([1,2,3,4])) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in test
TypeError: can't multiply sequence by non-int of type 'list'
>>> print(test())          
0
>>> l = [1,2,3,4] 
>>> print(test(l[0],l[1],l[2],l[3])) 
30
>>> print(test(*l))                  
30

可以看到test函数的参数number前面加了一个 “ * ” ,在调用函数时无需组装成列表或元组,直接使用逗号隔开即可,可以传入任意数量的参数,包括0个参数,但是这样我们想要传入列表时就会报错,我们可以先定义列表,然后同样使用” * “来把列表传入函数

4、关键字参数

  • 上面的可变参数允许传入0个或者任意数量的参数,传入的参数在函数调用时会自动组装成一个元组,而关键字参数允许传入0个或者任意数量的包含参数名的参数,这样参数会自动组装成一个字典
1、利用关键字参数定义函数test
>>> def test(name,age,**id):
...     print('name:',name,'age:',age,'id:',id) 
... 
>>> print(test('zhangsan',22))   #在只传入前两个参数时,可以看到最后一个参数id输出了一个空字典
name: zhangsan age: 22 id: 
None
>>> print(test('zhangsan',22,id=2223))     
name: zhangsan age: 22 id: 'id': 2223
None
>>> print(test('zhangsan',22,id=2223,other=5553))   #传入两个key=value
name: zhangsan age: 22 id: 'id': 2223, 'other': 5553
None
>>> aaa = 'id':2223,'other':5553   #定义一个aaa字典
>>> print(test('zhangsan',22,id=aaa['id'],other=aaa['other']))    #传入字典时,使用下标调用
name: zhangsan age: 22 id: 'id': 2223, 'other': 5553
None
>>> print(test('zhangsan',22,**aaa))         #和关键字参数一样,可以使用**一次性传入字典,需要注意的是,利用关键字参数把aaa字典传入到test函数中的**id参数,id参数会得到一个字典,而id的值只是aaa值的一份拷贝而已,修改id并不会影响aaa的值                 
name: zhangsan age: 22 id: 'id': 2223, 'other': 5553
None
  • 对于关键字参数来说,我们可以传入任意不受限制的关键字参数,而具体的值,需要在函数内部通过带**的参数(即**id)来检查

5、命名关键字参数

1、以上面的test函数为例,现在我们需要检查传入的参数是否有id和other参数,可以这样写:
>>> def test(name,age,**id):
...     if 'id' in id:
...             pass
...     if 'other' in id:
...             pass
...     print('name:',name,'age:',age,'id:',id) 
... 
>>> print(test('zhangsan',22,id=2222,other=3333,io=4444))
name: zhangsan age: 22 id: 'id': 2222, 'other': 3333, 'io': 4444
None

#但是发现我们仍然可以传入其他的参数,如果想要达到上面的效果,对传入的参数进行限制,我们可以使用命名关键字参数,例如:
>>> def test(name,age,*,id,other):
...     print('name:',name,'age:',age,'id:',id,'other:',other) 
... 
>>> print(test('zhangsan',22,id=3333,other=4444)) 
name: zhangsan age: 22 id: 3333 other: 4444
None
>>> print(test('zhangsan',22,id=3333,other=4444,io=5555))     #可以看到使用命名关键字参数后,除了id和other,继续传入io参数时会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: testPython基础03-函数详解

python vtk 通过回调函数监测键盘”Up”键动作,每按一次方向上键,actor变换一种颜色

怎么样用python编写2的n次方

python二元一次方程求根简单

python里面pow()函数作用是啥?

在 Python 中的文件末尾声明函数