开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python函数

在本文中,我们介绍了Python中的函数。

Python函数定义

函数是零个或多个输入参数到零个或多个输出参数的映射。

使用函数的优点是:

  • 减少代码重复
  • 将复杂问题分解成更简单的部分
  • 提高代码的清晰度
  • 代码重用
  • 信息隐藏

Python中的函数是一等公民。这意味着函数与Python中的其他对象具有平等的地位。函数可以分配给变量、存储在集合中或作为参数传递。这为语言带来了额外的灵活性。

Python函数类型

函数有两种基本类型:内置函数和用户定义函数。内置函数是Python语言的一部分;例如dirlenabs。用户定义函数是使用def关键字。

Python创建函数

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

def function():
    pass

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

该函数稍后在需要时执行。我们说我们调用函数。如果我们调用一个函数,函数体内的语句就会被执行。它们只有在函数被调用时才会被执行。

myfunc()

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

#!/usr/bin/python

"""
The ret.py script shows how to work with
functions in Python.
Author: Jan Bodnar
ZetCode, 2022
"""


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 with
functions in Python.
Author: Jan Bodnar
ZetCode, 2022

None C:/Users/Jano/PycharmProjects/Simple/simple.py

函数的定义必须先于它们的使用。否则解释器会报错NameError

#!/usr/bin/python

# func_prec.py


def f1():
    print("f1()")


f1()
#f2()


def f2():
    print("f2()")

在上面的例子中,我们有两个函数定义。注释一行。函数调用不能在其定义之前。

#f2()


def f2():
    print("f2()")

我们只能在定义之后调用f2。取消注释我们得到一个NameError

在哪里定义函数

函数可以在模块、类或另一个函数中定义。在类中定义的函数称为方法

#!/usr/bin/python

# defining.py


class Some():

    @staticmethod
    def f():
        print("f() method")


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


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


Some.f()
f()
g()

在这个例子中,我们在三个不同的地方定义了一个f函数。

# defining.py

class Some():

    @staticmethod
    def 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()

通过在方括号中指定类名、dotoperator和函数名来调用静态方法。其他函数使用它们的名称和方括号调用。

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

Python函数是对象

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

#!/usr/bin/python

# fun_obj.py


def 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函数是否是对象的实例。Python中的所有对象都继承自该基本实体。

print(id(f))

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

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

对象可能有属性;我们打印函数的两个属性:__doc____name__

$ ./fun_obj.py
True
140353774014536
This function prints a message
f

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

#!/usr/bin/python

# fun_coll.py


def f():
    pass


def g():
    pass


def 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)

我们将fg函数传递给h函数。

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

Python中的三种函数

从一个特定的角度来看,我们可以区分三种功能。始终可用的函数、必须导入的外部模块中包含的函数以及程序员使用def关键字定义的函数。

#!/usr/bin/python

from math import sqrt


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


print(abs(-1))
print(cube(9))
print(sqrt(81))

上述代码中存在三种函数。

from math import sqrt

sqrt函数是从math模块导入的。

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

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

print(abs(-1))

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

Python返回关键字

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

#!/usr/bin/python

# returning.py


def 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.py
27
Computation finished.
Ready.
None

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

#!/usr/bin/python

# returning2.py

n = [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本质上是动态的。可以重新定义一个已经定义的函数。

#!/usr/bin/python

# redefinition.py

from time import gmtime, strftime


def 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函数参数

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

#!/usr/bin/python

# fahrenheit.py


def C2F(c):
    return c * 9/5 + 32


print(C2F(100))
print(C2F(0))
print(C2F(30))

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

$ ./fahrenheit.py
212
32
86

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

#!/usr/bin/python

# fun_implicit.py


def power(x, y=2):

    r = 1

    for i in range(y):
        r = r * x

    return r


print(power(3))
print(power(3, 3))
print(power(5, 5))

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

$ ./fun_implicit.py
9
27
3125

Python函数可以用关键字指定它们的参数。这意味着当调用一个函数时,我们同时指定了一个关键字和一个值。当我们有多个参数并且在没有关键字的情况下使用它们时,我们传递这些参数的顺序是至关重要的。如果我们期望一个名字、年龄或性别一个没有关键字的函数,我们不能改变它们的顺序。如果我们使用关键字,我们可以。

#!/usr/bin/python

# fun_keywords.py

def 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:  43
Sex:  M
Name:  Joan
Age:  24
Sex:  F
#!/usr/bin/python

# fun_keywords2.py


def 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中的函数可以接受任意数量的参数。

#!/usr/bin/python

# arbitrary_args.py


def do_sum(*args):
    """Function returns the sum
of all values"""

    r = 0

    for i in args:
        r += i

    return r


print(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 sum
of all values
6
15

我们还可以在我们的函数中使用**结构。在这种情况下,该函数将接受字典。字典有任意长度。然后我们可以像往常一样正常解析字典。

#!/usr/bin/python

# details.py


def display(**details):

    for i in details:
        print(f"{i}: {details[i]}")


display(name="Larry", age=43, sex="M")

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

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

Python通过引用传递参数

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

#!/usr/bin/python

# passing_by_reference.py

n = [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函数中是如何使用的。

#!/usr/bin/python

# local_variable.py

name = "Jack"


def f():
    name = "Robert"
    print("Within function", name)


print("Outside function", name)
f()

在函数体中定义的变量具有局部作用域。它仅在函数体内有效。

$ ./local_variable.py
Outside function Jack
Within function Robert
#!/usr/bin/python

# global_variable.py

name = "Jack"


def f():
    print("Within function", name)


print("Outside function", name)
f()

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

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

但是如果我们想改变一个函数中的全局变量,我们必须使用global关键字。

#!/usr/bin/python

# global_variable2.py

name = "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上有一个Pythonlambda函数教程。

#!/usr/bin/python

# lambda_fun.py

y = 6

z = lambda x: x * y
print(z(8))

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

z = lambda x: x * y

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

print(z(8))

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

$ ./lambda_fun.py
48

lambda函数可以优雅地与Python语言的其他功能部分一起使用,例如mapfilter函数。

#!/usr/bin/python

# lambda_fun2.py

cs = [-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教程。

未经允许不得转载:我爱分享网 » Python函数

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏