本系列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 函数的详细内容...