好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Python ——10.Python 函数

本系列Python教程持续更新中,希望对大家有帮助,喜欢的可以点击一键三连加评论,还可以微信搜索【程序员二黑】关注我,免费领取视频教程

系列目录:python教程——目录!

Python 函数

原文: http://zetcode测试数据/lang/python/functions/

在 Python 编程教程的这一部分中,我们介绍了 Python 中的函数。

Python 函数定义

函数是用于执行特定操作的可重用代码块。 使用函数的优点是:

减少代码重复 将复杂的问题分解成更简单的部分 提高代码的清晰度 重用代码 信息隐藏 Python 中的函数是一等公民。 这意味着函数与 Python 中的其他对象具有同等的状态。 可以将函数分配给变量,存储在集合中或作为参数传递。 这给语言带来了额外的灵活性。

Python 函数类型

函数有两种基本类型:内置函数和用户定义函数。 内置函数是 Python 语言的一部分; 例如dir(),len()或abs()。 用户定义的函数是使用def关键字创建的函数。

Python 创建函数

使用def关键字创建一个函数。 函数块中的语句必须缩进。

def?function():pass

def关键字后跟带有圆括号和冒号的函数名称。 缩进语句形成函数的主体。

该函数稍后在需要时执行。 我们说我们调用函数。 如果我们调用一个函数,则会执行函数体内的语句。 在调用函数之前,它们不会执行。

myfunc()

要调用函数,我们用圆括号指定函数名称。

ret.py

#!/usr/bin/env?python"""
The?ret.py?script?shows?how?to?work?with
functions?in?Python.
Author:?Jan?Bodnar
ZetCode,?2019
"""def?show_module_name():print(__doc__)def?get_module_file():return?__file__

a?=?show_module_name()b?=?get_module_file()print(a,?b)

脚本顶部的字符串称为文档字符串。 它记录了当前脚本。 我们放入 Python 代码的文件称为模块。

我们定义两个函数。 第一个函数打印模块文档字符串。 第二个返回模块的路径。 函数可能会或可能不会返回值。 如果函数没有返回值,则它隐式返回None。 __doc__和__file__是特殊的状态属性。 请注意,属性的两侧都有两个下划线。

$?./ret.py

The?ret.py?script?shows?how?to?work?withfunctions?in?Python.Author:?Jan?Bodnar
ZetCode,?2019None?C:/Users/Jano/PycharmProjects/Simple/simple.py

这是程序的输出。

函数的定义必须先于其用法。 否则,口译员会抱怨NameError。

func_prec.py#!/usr/bin/env?python#?func_prec.pydef?f1():print("f1()")f1()#f2()def?f2():print("f2()")

在上面的示例中,我们有两个函数定义。 一行被注释。 函数调用不能超出其定义。

#f2()def?f2():print("f2()")

仅在定义后才能调用f2()。 取消注释该行,我们得到一个NameError。

在哪里定义函数

可以在模块,类或其他函数中定义函数。 在类内部定义的函数称为方法。

defining.py#!/usr/bin/env?python#?defining.pyclass?Some():@staticmethoddef?f():print("f()?method")def?f():print("f()?function")def?g():def?f():print("f()?inner?function")f()Some.f()f()g()

在此示例中,我们在三个不同的位置定义了f()函数。

#?defining.pyclass?Some():@staticmethoddef?f():print("f()?method")

静态方法在Some类中用装饰器定义。

def?f():print("f()?function")

该函数在模块中定义。

def?g():def?f():print("f()?inner?function")f()

此处,f()函数在另一个g()函数内部定义。 这是一个内部函数。

Some.f()f()g()

通过使用方括号指定类名称,点运算符和函数名称来调用静态方法。 其他函数使用其名称和方括号来调用。

$?./defining.py
f()?method
f()?function
f()?inner?function

这是输出。

Python 函数是对象

Python 中的函数是对象。 它们可以像 Python 中的其他对象一样进行操作。 因此,职能被称为头等公民。 在其他 OOP 语言(例如 Java 或 C# )中,情况并非如此。

fun_obj.py#!/usr/bin/env?python#?fun_obj.pydef?f():"""This?function?prints?a?message?"""print("Today?it?is?a?cloudy?day")print(isinstance(f,?object))print(id(f))print(f.__doc__)print(f.__name__)

在此脚本中,我们表明我们的函数也是一个对象。

def?f():"""This?function?prints?a?message?"""print("Today?it?is?a?cloudy?day")

我们定义一个f()函数。 它将消息打印到控制台。 它还具有一个文档字符串。

print(isinstance(f,?object))

isinstance()函数检查f()函数是否是object的实例。 Python 中的所有对象均从该基本实体继承。

print(id(f))

Python 中的每个对象都有一个唯一的 ID。 id()函数返回对象的 ID。

print(f.__doc__)print(f.__name__)

对象可能具有属性; 我们打印函数的两个属性: doc__和__name 。

$?./fun_obj.pyTrue140353774014536This?function?prints?a?message
f

这是程序的输出。

函数可以存储在集合中并传递给其他函数。

fun_coll.py#!/usr/bin/env?python#?fun_coll.pydef?f():passdef?g():passdef?h(f):print(id(f))a?=?(f,?g,?h)for?i?in?a:print(i)h(f)h(g)我们定义了三个函数。?我们将它们放在一个元组中,然后将它们传递给函数。

a?=?(f,?g,?h)for?i?in?a:print(i)

我们将三个函数对象放在一个元组中,并使用for循环遍历它。

h(f)h(g)

我们将f()和g()函数传递给h()函数。

$?./fun_coll.py<function?f?at?0x0000015B998E9D08><function?g?at?0x0000015B998E9E18><function?h?at?0x0000015B998E9840>14929299120721492929912344

这是fun_coll.py程序的输出。

Python 中的三种函数

从特定的角度来看,我们可以辨别出三种函数。 始终可供使用的函数,必须导入的外部模块中包含的函数以及由程序员使用def关键字定义的函数。

three_kinds.py#!/usr/bin/env?pythonfrom?math?import?sqrtdef?cube(x):return?x?*?x?*?xprint(abs(-1))print(cube(9))print(sqrt(81))

上面的代码中存在三种函数。

from?math?import?sqrt
sqrt()函数是从数学模块导入的。def?cube(x):return?x?*?x?*?x

cube()函数是一个自定义函数。

print(abs(-1))

abs()函数是易于访问的内置函数。 它是语言核心的一部分。

Python return关键字

创建一个函数来执行特定任务。 通常,这种任务会产生结果。 return关键字用于从函数返回值。 函数可能会也可能不会返回值。 如果一个函数没有return关键字,它将发送None。

returning.py#!/usr/bin/env?python#?returning.pydef?show_message(msg):print(msg)def?cube(x):return?x?*?x?*?x

x?=?cube(3)print(x)show_message("Computation?finished.")print(show_message("Ready."))

我们定义了两个函数。 一个使用return关键字,另一个则不使用。

def?show_message(msg):print(msg)

show_message()函数不会显式返回值。 它在控制台上显示一条消息。

def?cube(x):return?x?*?x?*?x

cube()函数计算一个表达式,并使用return关键字返回其结果。

x?=?cube(3)

在这一行中,我们称为cube()函数。 返回cube()函数的计算结果,并将其分配给x变量。 现在保存结果值。

show_message("Computation?finished.")

我们以消息为参数调用show_message()函数。 该消息将打印到控制台。 我们不期望此函数有值。

print(show_message("Ready."))

此代码产生两行。 一种是通过show_message()函数打印的消息。 另一个是None值,该值由没有return语句的函数隐式发送。

$?./returning.py27Computation?finished.Ready.None

这是示例输出。

我们可以从函数中发送多个值。 return关键字之后的对象用逗号分隔。

returning2.py#!/usr/bin/env?python#?returning2.pyn?=?[1,?2,?3,?4,?5]def?stats(x):_mx?=?max(x)_mn?=?min(x)_ln?=?len(x)_sm?=?sum(x)return?_mx,?_mn,?_ln,?_sm

mx,?mn,?ln,?sm?=?stats(n)print(stats(n))print(mx,?mn,?ln,?sm)

有stats()函数的定义。 此函数返回四个值。

return?_mx,?_mn,?_ln,?_sm

return关键字发回四个数字。 这些数字用逗号分隔。 实际上,我们已经发送了包含这四个值的元组。 我们也可以返回列表而不是元组。

mx,?mn,?ln,?sm?=?stats(n)

返回的值分配给局部变量。

$?./returning2.py(5,?1,?5,?15)5?1?5?15

这是输出。

Python 函数重新定义 Python 本质上是动态的。 可以重新定义已经定义的函数。

redefinition.py#!/usr/bin/env?python#?redefinition.pyfrom?time?import?gmtime,?strftimedef?show_message(msg):print(msg)show_message("Ready.")def?show_message(msg):print(strftime("%H:%M:%S",?gmtime()))print(msg)show_message("Processing.")

我们定义一个show_message()函数。 稍后,我们提供相同函数的新定义。

from?time?import?gmtime,?strftime

从时间模块中,我们导入两个函数,用于计算当前时间。

def?show_message(msg):print(msg)

这是函数的第一个定义。 它仅将消息打印到控制台。

def?show_message(msg):print(strftime("%H:%M:%S",?gmtime()))print(msg)

在源代码的后面,我们设置了showMessage()函数的新定义。 该消息之前带有时间戳。

$?./redefinition.py
Ready.23:49:33?Processing.

这是输出。

Python 函数参数

大多数函数接受参数。 参数是发送到函数的值。 这些函数处理这些值并有选择地返回一些值。

fahrenheit.py#!/usr/bin/env?python#?fahrenheit.pydef?C2F(c):return?c?*?9/5?+?32print(C2F(100))print(C2F(0))print(C2F(30))

在我们的示例中,我们将摄氏温度转换为华氏温度。 C2F()函数接受一个参数c,即摄氏温度。

$?./fahrenheit.py2123286

Python 函数中的参数可能具有隐式值。 如果未提供任何值,则使用隐式值。

fun_implicit.py#!/usr/bin/env?python#?fun_implicit.pydef?power(x,?y=2):r?=?1for?i?in?range(y):r?=?r?*?xreturn?rprint(power(3))print(power(3,?3))print(power(5,?5))

在这里,我们创建了幂函数。 该函数有一个带有隐式值的参数。 我们可以使用一个或两个参数来调用该函数。

$?./fun_implicit.py9273125

Python 函数可以使用关键字指定其参数。 这意味着在调用函数时,我们同时指定了关键字和值。 当我们有多个参数并且不使用关键字而使用它们时,传递这些参数的顺序至关重要。 如果我们期望在没有关键字的函数中使用名称,年龄或性别,则无法更改其顺序。 如果使用关键字,我们可以。

fun_keywords.py#!/usr/bin/env?python#?fun_keywords.pydef?display(name,?age,?sex):print("Name:?",?name)print("Age:?",?age)print("Sex:?",?sex)display("Lary",?43,?"M")display("Joan",?24,?"F")

在此示例中,我们指定参数的顺序很重要。 否则,我们将得到错误的结果。

$?./fun_keywords.py
Name:??Lary
Age:??43Sex:??M
Name:??Joan
Age:??24Sex:??F
fun_keywords2.py#!/usr/bin/env?python#?fun_keywords2.pydef?display(name,?age,?sex):print("Name:?",?name)print("Age:?",?age)print("Sex:?",?sex)display(age=43,?name="Lary",?sex="M")display(name="Joan",?age=24,?sex="F")

现在我们用它们的关键字来调用函数。 可以更改顺序,尽管不建议这样做。 请注意,我们不能在关键字参数之后使用非关键字参数。 这将导致语法错误。

display("Joan",?sex="F",?age=24)

这是法律构想。 非关键字参数后可以跟关键字参数。

display(age=24,?name="Joan",?"F")

这将导致语法错误。 非关键字参数不能跟在关键字参数之后。

Python 中的函数可以接受任意数量的参数。

arbitrary_args.py#!/usr/bin/env?python#?arbitrary_args.pydef?do_sum(*args):"""Function?returns?the?sum
of?all?values"""r?=?0for?i?in?args:r?+=?ireturn?rprint(do_sum.__doc__)print(do_sum(1,?2,?3))print(do_sum(1,?2,?3,?4,?5))

我们使用*运算符表示该函数接受任意数量的参数。 do_sum()函数返回所有参数的总和。 函数主体中的第一个字符串称为函数文档字符串。 用于记录函数。 该字符串必须用三引号引起来。

$?./arbitrary_args.py
Function?returns?the?sumof?all?values615

我们还可以在函数中使用**构造。 在这种情况下,该函数将接受字典。 字典有任意长度。 然后,我们通常可以照常解析字典。

details.py#!/usr/bin/env?python#?details.pydef?display(**details):for?i?in?details:print(f"{i}:?{details[i]}")display(name="Larry",?age=43,?sex="M")

本示例说明了这种情况。 我们可以提供任意数量的键值参数。 该函数将处理所有这些。

$?./details.py
age:?43name:?Larry
sex:?M

Python 通过引用传递参数 函数的参数通过引用传递。 一些语言将对象的副本传递给函数。 通过引用传递对象有两个重要结论:a)与传递对象副本相比,此过程更快。 b)在函数中修改的可变对象将永久更改。

passing_by_reference.py#!/usr/bin/env?python#?passing_by_reference.pyn?=?[1,?2,?3,?4,?5]print("Original?list:",?n)def?f(x):x.pop()x.pop()x.insert(0,?0)print("Inside?f():",?x)f(n)print("After?function?call:",?n)

在我们的示例中,我们将整数列表传递给函数。 该对象在函数体内被修改。 调用该函数(原始对象)后,将修改整数列表。

def?f(x):x.pop()x.pop()x.insert(0,?0)print("Inside?f():",?x)

在函数主体中,我们使用原始对象。 不带对象的副本。 在许多编程语言中,默认情况下,我们将收到对象的副本。

$?./passing_by_reference.py
Original?list:?[1,?2,?3,?4,?5]Inside?f():?[0,?1,?2,?3]After?function?call:?[0,?1,?2,?3]

一旦列表被修改,它就被永久修改了。

Python 全局和局部变量

接下来,我们将讨论如何在 Python 函数中使用变量。

local_variable.py#!/usr/bin/env?python#?local_variable.pyname?=?"Jack"def?f():name?=?"Robert"print("Within?function",?name)print("Outside?function",?name)f()

在函数体中定义的变量具有局部范围。 它仅在函数体内有效。

$?./local_variable.py
Outside?function?Jack
Within?function?Robert
这是示例输出。

global_variable.py#!/usr/bin/env?python#?global_variable.pyname?=?"Jack"def?f():print("Within?function",?name)print("Outside?function",?name)f()

默认情况下,我们可以在函数体内获取全局变量的内容。

$?./global_variable.py
Outside?function?Jack
Within?function?Jack

但是,如果要更改函数中的全局变量,则必须使用global关键字。

global_variable2.py#!/usr/bin/env?python#?global_variable2.pyname?=?"Jack"def?f():global?name
????name?=?"Robert"print("Within?function",?name)print("Outside?function",?name)f()print("Outside?function",?name)

现在,我们将在函数内部更改全局名称变量的内容。

global?name
name?=?"Robert"

使用global关键字,我们引用在函数主体外部定义的变量。 该变量被赋予一个新值。

$?./global_variable2.py
Outside?function?Jack
Within?function?Robert
Outside?function?Robert

Python 匿名函数

可以在 Python 中创建匿名函数。 匿名函数没有名称。 使用lambda关键字,几乎无法创建任何匿名函数。 Python 程序员也将匿名函数称为 lambda 函数。 它们是 Python 中合并的函数示例的一部分。

Lambda 函数仅限于单个表达式。 它们可以在可以使用常规函数的任何地方使用。 ZetCode 上有一个 Python lambda 函数教程。

lambda_fun.py#!/usr/bin/env?python#?lambda_fun.pyy?=?6z?=?lambda?x:?x?*?yprint(z(8))

这是 lambda 函数的一个小例子。

z?=?lambda?x:?x?*?y

lambda关键字创建一个匿名函数。 x是传递给 lambda 函数的参数。 参数后跟一个冒号。 冒号旁边的代码是在调用 lambda 函数时执行的表达式。 lambda 函数被分配给z变量。

print(z(8))

lambda 函数被执行。 数字 8 传递给匿名函数,结果返回 48。 请注意,z不是此函数的名称。 它只是分配了匿名函数的变量。

$?./lambda_fun.py48

这是示例的输出。

lambda?函数可以与map()或filter()函数之类的?Python?语言的其他函数部件完美地结合使用。

lambda_fun2.py#!/usr/bin/env?python#?lambda_fun2.pycs?=?[-10,?0,?15,?30,?40]ft?=?map(lambda?t:?(9.0/5)*t?+?32,?cs)print(list(ft))

在示例中,我们列出了摄氏温度。 我们创建一个包含华氏温度的新列表。

ft?=?map(lambda?t:?(9.0/5)*t?+?32,?cs)

map()函数将匿名函数应用于cs列表的每个元素。 它返回计算出的华氏温度的可迭代值。

$?./lambda_fun2.py[14.0,?32.0,?59.0,?86.0,?104.0]

这是示例输出。

本章是关于 Python 中的函数的。

查看更多关于Python ——10.Python 函数的详细内容...

  阅读:31次