首页 > 编程语言 >Python 函数

Python 函数

时间:2023-10-28 10:00:55浏览次数:53  
标签:... 函数 Python abs 参数 func def

函数


当编写的代码出现有规律的重复时,这个时候就要考虑定义函数,将这些代码提取定义成一个函数,方便调用。

Python 提供许多内置函数,可以根据需要调用相应的函数实现想要的功能。同样 Python 也能够灵活地自定义函数。

调用函数


介绍如何定义函数前,先讲下如何调用函数。

Python 提供许多内置函数,这些函数都是可以直接调用的。包括前面的篇幅,其实也有调用函数实现一些功能。这里大致讲下函数的调用。

举个例子,求绝对值的函数 abs(),这个函数只接受一个参数。函数的使用可以查看官方文档:

http://docs.python.org/3/library/functions.html#abs

也可以在交互式命令行下通过 help(abs) 来查看 abs 函数的帮助信息。

现在尝试调用 abs() 函数:

>>> abs(-1)
1
>>> abs(1)
1

因为 abs 只接受一个参数,若是传入的参数个数不为 1,会报 TypeError 的错误,信息中也会给出错误的提示:

>>> abs(-1, 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)

这里表示,abs() 函数只接受一个参数,但是却提供了两个参数。

abs() 的参数接收的是数值,若是传入的类型错误,同样也会报错:

>>> abs('1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'

这里给出的错误提示表示 str 不是可接受的类型。

这就是函数调用,同时也需要注意的一些地方。要了解函数调用需要的几个参数,以及参数的类型。

定义函数


现在讲一下函数的定义,函数定义要使用 def 语句,后面紧跟的是函数名,括号,包含在括号内的参数以及冒号,然后在缩进块编写函数体,如果有返回值的话,则使用 return 语句返回。

还是以求绝对值为例,这里自定义函数实现:

def my_abs(num):
    if num >= 0:
        return num
    else:
        return -num

当执行 return 时,函数即为执行完毕,直接返回结果。例子中,简单使用了条件判断,函数内部可以通过使用条件判断以及循环,实现非常复杂的逻辑。

有些函数并没有 return 语句。但是函数执行完毕后同样会返回结果,只是结果为 None。所以 return None,也可以写为 return

现在我们尝试调用自己编写的函数 my_abs:

>>> my_abs(1)
1
>>> my_abs(-1)
1
>>> my_abs('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in my_abs
TypeError: '>=' not supported between instances of 'str' and 'int'

这里会看到当参数接受字符串的时候,出现的错误与 Python 提供的 abs 出错信息不一样。

这里我们添加对参数的检查,只允许整数和浮点数类型的参数。可以用 isinstance() 函数实现数据类型检查。

>>> def my_abs(num):
...     if not isinstance(num, (int, float)):
...         raise TypeError("bad operand type")
...     if num >= 0:
...         return num
...     else:
...         return -num
...

再次尝试调用该函数:

>>> my_abs('1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in my_abs
TypeError: bad operand type

这样,看起来就更像 abs() 函数。

pass 语句

有时候,可能并没有想好要编写怎样的函数,但是想先定义,在后续补充代码。这个时候,pass 语句就派上用场。

pass 语句能够做占位符使用,可以在函数体中先将这个语句放进来,让编写的其他代码运行起来。等到后续要补充的时候再去掉 pass 语句进行修改。例如:

def no_idea():
    pass

这里如果函数体内没有这个 pass 语句,运行就会提示有语法错误。

返回多个值

上面提及的自定义函数,包括带 pass 语句的空函数(返回的是 None),返回的是一个值。

为了可以返回多个值,可以直接返回一个元组,例如:

>>> def my_func():
...     return 1, 2, 3
...
>>> a, b, c = my_func()
>>> a
1
>>> b
2
>>> c
3

虽然上面的函数看上去是返回了多个值,但实际上是先创建一个元组然后返回的。

其实我们使用的是逗号来生成一个元组,而不是用括号。例如:

>>> a = (1,2) # 带括号
>>> a
(1, 2)
>>> b = 1,2 # 不带括号
>>> b
(1, 2)

所以,这前面定义返回多值的函数,其实返回的是元组。若是赋值给单个变量,那么这个变量其实就是返回的那个元组本身:

>>> d = my_func()
>>> d
(1, 2, 3)

函数参数


位置参数

先定义一个函数:

>>> def func(a, b):
...     print('a = {},b = {}'.format(a, b))
...
>>> func(1,2)
a = 1,b = 2

在这里,就是 a 和 b,两个参数都是位置参数,调用的时候,依次将两个值按照顺序依次赋值给参数 a 和 b

默认参数

延用上面的例子,在这里,我们调用的时候只赋值给 a:

>>> func(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required positional argument: 'b'

这里错误提示:调用参数缺少一个位置参数 b

这个时候,就可以考虑使用默认参数:

>>> def func(a, b=2):
...     print('a = {}, b = {}'.format(a, b))
...
>>> func(1)
a = 1, b = 2

可以看到当调用 func(1) 时,就相当于调用了 func(1, 2)

这里有些地方需要注意:

  • 必选的参数一定要放在默认参数前面,否则会报错。
  • 默认参数必须指向不变对象

第一点比较好理解,如果默认参数在必选参数前面,由于传入的值会按照位置给参数赋值。例如下面的错误示例(下面这种写法仅做错误示范,不建议如此编写。当然这样编写也会报错):

def func(a=1, b):
    return a, b

假设我们调用的时候,以这样的逻辑想,现在 a 有默认值,只给 b 赋值就可以了。但是赋值会按照位置赋值。比如调用 func(2),其实这里是将 2 赋值给了 a,替代了原来的 1,最终 b 还是缺少赋值。

第二点,必须指向不变对象,千万不能像下面这样编写代码:

def func(a, b=[]):
    ....

这样写的话,后面会遇到很多的麻烦。b 作为可修改的对象,这些修改会影响到下次调用这个函数的默认值。比如:

>>> def func(a, b=[]):
...     print(b)
...     return b
...
>>> x = func(1)
[]
>>> x.append(2)
>>> x.append('wow!')
>>> x
[2, 'wow!']
>>> func(1)
[2, 'wow!']

可以看到当再次调用 func(1) 的时候,结果已经变了,这个并不是原来的初衷。

如果真的需要使用列表,最好先使用 None,然后在函数里面用相应的逻辑检查。

当然测试 None 的时候要需要注意,使用 is 操作符是非常重要的。

def func(a, b=None):
    if not b: # 不建议这样写,建议用 b is None:代替
        b = []

上面不建议使用 if not b: ,如果这样的话,None 会被当成是 False,而长度为 0 的字符串,列表,元组,字典等都可能被当成 False。这一点也要注意。

可变参数

上面提及的函数都是固定数量的位置参数,为了实现一个能接受任意数量的位置参数的函数,可以使用一个 * 参数。例如:

>>> def func(*nums):
...     sum = 0
...     for num in nums:
...         sum += num
...     return sum
...

>>> func(1,2)
3
>>> func(1,2,3)
6

这样就实现了可以传入任意数量的参数的位置参数。

关键字参数

若是要实现接受任意数量的关键字参数,可以使用 ** 开头的参数。比如:

>>> def info(name, age, **kw):
...     print('name:', name, 'age:', age, 'other:', kw)
...
>>> info('大梦三千秋', 0)
name: 大梦三千秋 age: 0 other: {} 
>>> info('大梦三千秋', 0, city='Guangzhou')
name: 大梦三千秋 age: 0 other: {'city': 'Guangzhou'}
>>> info('大梦三千秋', 0, city='Guangzhou', gender='male')
name: 大梦三千秋 age: 0 other: {'city': 'Guangzhou', 'gender': 'male'}

这样就实现了传入任意个数的关键字参数。这里,关键字参数允许传入 0 个或任意个参数名的参数,函数内部会自动组成一个 dict,如上示例。

命名关键字参数

命名关键字参数,其实是将关键字参数放到某个 * 参数后面或者单个 * 后面,例如:

>>> def info(name, age, *, city):
...     print(name, age, city)
...
>>> info('大梦三千秋', 0, city='Guangzhou')
大梦三千秋 0 Guangzhou

这里注意调用方式,一定要传入参数名,若是没有传入参数名,则会报错:

>>> info('大梦三千秋', 0, 'Guangzhou')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: info() takes 2 positional arguments but 3 were given

上面的提示中说只需要 2 个位置参数但是传入的参数有 3 个这时因为缺少参数名 city,解释器将 3 个参数都视为位置参数,但 info 函数只接受 2 个位置参数。

参数顺序

这里提及到的参数有位置(必选)参数、默认参数、可变参数、关键字参数和命名关键字参数。但是需要注意参数的定义顺序:

必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

虽然上面的参数都可以组合在一起,但是不建议这样做,这样会导致可理解性变差。


标签:...,函数,Python,abs,参数,func,def
From: https://blog.51cto.com/u_16224822/8067632

相关文章

  • Python时间序列分析库介绍:statsmodels、tslearn、tssearch、tsfresh
    时间序列分析在金融和医疗保健等领域至关重要,在这些领域,理解随时间变化的数据模式至关重要。在本文中,我们将介绍四个主要的Python库——statmodels、tslearn、tssearch和tsfresh——每个库都针对时间序列分析的不同方面进行了定制。这些库为从预测到模式识别的任务提供了强大的工......
  • Linux文件和目录操作函数
    1.文件系统1.1文件存储1.1.1inode本质:struct结构体。存储文件的属性信息。如:权限、类型、大小、时间、用户、盘块位置大多数的inode保存在磁盘中,少量常用、近期使用的inode保存在内存中1.1.2dentry目录项本质:struct结构体{文件名、inode号...}文......
  • redshift DATE_TRUNC函数 查询日期上个月的26号到当前月的26号
    redshiftDATE_TRUNC函数查询日期上个月的26号到当前月的26号#redshift脚本#2023-08-0100:00:00.000selectDATE_TRUNC('month',current_date-INTERVAL'2month')#2023-08selectleft(DATE_TRUNC('month',current_date-INTERVAL'2month......
  • python123 第二章:我的读书笔记
    print("后四位学号:3114")print("\n03")#03运行超市抹零结账行为‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪......
  • [Python急救站]草莓熊的绘制
    草莓熊也是一个热门的图案,今天就用Pythonimportturtleast#设置背景颜色,窗口位置以及大小t.colormode(255)#颜色模式t.speed(0)t.screensize(850,760)t.setup(width=850,height=760,startx=None,starty=None)#绘图窗口的大小和起始坐标t.resizemode('nores......
  • Python 利用pandas和mysql-connector获取Excel数据写入到MySQL数据库
    如何将Excel数据插入到MySQL数据库中在实际应用中,我们可能需要将Excel表格中的数据导入到MySQL数据库中,以便于进行进一步的数据分析和处理。本文将介绍如何使用Python将Excel表格中的数据插入到MySQL数据库中。导入必要的库首先,我们需要导入pandas库和MySQLConnector/Python库......
  • Python 中多态性的示例和类的继承多态性
    单词"多态"意味着"多种形式",在编程中,它指的是具有相同名称的方法/函数/操作符,可以在许多不同的对象或类上执行。函数多态性一个示例是Python中的len()函数,它可以用于不同的对象。字符串对于字符串,len()返回字符的数量:示例x="HelloWorld!"print(len(x))元组......
  • Python根据列表在指定目录寻找对应前缀的文件
    现在有一个txt列表,里面包含的是一些文件名,如a,b等等,现在需求是在一个多级文件夹下,需要寻找以a为名字的任何格式文件,如a.001,a.002等等,寻找这个txt列表里包含的文件名的对应文件,复制到指定文件夹下importosimportshutil#读取文件名列表withopen('msg.txt','r')asfile:......
  • 如何通过python实现导出题库到pdf?
    要通过Python实现将题库导出为PDF,你可以使用第三方库如pdfkit或weasyprint来完成。以下是一种可行的方法:安装所需的库:使用pip命令安装pdfkit或weasyprint库。准备HTML模板:创建一个HTML模板文件,其中包含题目、答案、图片等内容。确保在HTML中使用CSS样式来控制文本和图像的外......
  • 无涯教程-Clojure - re-pattern函数
    re-pattern返回java.util.regex.Pattern的实例。然后将其用于其他模式匹配方法。re-pattern-语法(repatternpat)参数   - "pat"是需要形成的pattern。返回值 - 类型为java.util.regex.Pattern的模式对象。re-pattern-示例(nsclojure.examples.example......