功能
功能是可重复使用的程序(在java中成为方法/函数 )。它们允许您为一个语句块命名,允许您在程序中的任何位置使用指定的名称运行该块,并且可以多次。这称为调用函数。我们已经使用了许多内置函数,如len
和range
。
该函数的概念可能是在任何非平凡的软件(在任何编程语言)中最重要的组成部分,因此,我们将探讨在本章中的功能各个方面。
使用d
此ef
关键字定义函数。在关键字后面是函数的标识符名称,后跟一对括号,它们可以包含一些变量名称,以及结束该行的最后一个冒号。接下来是作为此函数一部分的语句块。一个例子将表明这实际上非常简单:
示例(另存为function1.py
):
def say_hello():
# block belonging to the function
print('hello world')
# End of function
say_hello() # call the function
say_hello() # call the function again
输出:
$ python function1.py
hello world
hello world
这个怎么运作
我们say_hello
使用如上所述的语法定义一个函数。此函数不带参数,因此括号中没有声明变量。函数的参数只是函数的输入,因此我们可以向它传递不同的值并返回相应的结果。
请注意,我们可以两次调用相同的函数,这意味着我们不必再次编写相同的代码。
功能参数
函数可以接受参数,这些参数是您提供给函数的值,以便函数可以利用这些值执行某些操作。这些参数就像变量一样,只是在调用函数时定义了这些变量的值,并且在函数运行时已经赋值。
参数在函数定义中的括号对中指定,以逗号分隔。当我们调用函数时,我们以相同的方式提供值。请注意使用的术语 - 函数定义中给出的名称称为参数,而函数调用中提供的值称为参数。
示例(另存为function_param.py
):
def print_max(a, b):
if a > b:
print(a, 'is maximum')
elif a == b:
print(a, 'is equal to', b)
else:
print(b, 'is maximum')
# directly pass literal values
print_max(3, 4)
x = 5
y = 7
# pass variables as arguments
print_max(x, y)
输出:
$ python function_param.py
4 is maximum
7 is maximum
这个怎么运作
在这里,我们定义一个名为的函数print_max
,它使用两个名为a
b
。我们使用简单的if..else
语句找出更大的数字然后打印更大的数字。
我们第一次调用函数时print_max
,我们直接提供数字作为参数。在第二种情况下,我们使用变量作为参数调用函数。print_max(x, y)
导致将参数值x
赋给参数a
,并将参数值y
赋给参数b
。print_max
在这两种情况下,该功能的工作方式相同。
局部变量
在函数定义中声明变量时,它们与函数外部使用相同名称的其他变量无关 - 即变量名称是函数的本地变量。这称为变量的范围。所有变量都具有从名称定义开始声明的块的范围。
示例(另存为function_local.py
):
x = 50
def func(x):
print('x is', x)
x = 2
print('Changed local x to', x)
func(x)
print('x is still', x)
输出:
$ python function_local.py
x is 50
Changed local x to 2
x is still 50
这个怎么运作
我们第一次使用函数体中的第一行打印名称x的值时,Python使用在主块中声明的参数值,在函数定义之上。
接下来,我们赋值2
给x
。该名称x
是我们函数的本地名称。因此,当我们更改x
函数中的值时,x
主块中定义的值不受影响。
使用最后一个print
语句,我们显示x
主块中定义的值,从而确认它实际上不受先前调用的函数内的本地赋值的影响。
该global
声明
如果要为程序顶层定义的名称赋值(即不在函数或类的任何类型的范围内),那么你必须告诉Python该名称不是本地的,而是全局的。我们使用该global
声明来做到这一点。如果没有global
语句,则无法为函数外部定义的变量赋值。
您可以使用在函数外部定义的此类变量的值(假设函数中没有相同名称的变量)。但是,这不是鼓励的,应该避免,因为程序的读者不清楚该变量的定义在哪里。使用该global
语句可以清楚地表明变量是在最外层的块中定义的。
示例(另存为function_global.py
):
x = 50
def func():
global x
print('x is', x)
x = 2
print('Changed global x to', x)
func()
print('Value of x is', x)
输出:
$ python function_global.py
x is 50
Changed global x to 2
Value of x is 2
这个怎么运作
该global
语句用于声明这x
是一个全局变量 - 因此,当我们x
在函数内部赋值时,当我们使用x
主块中的值时,会反映出这种变化。
您可以使用相同的global
语句指定多个全局变量,例如global x, y, z
。
默认参数值
对于某些函数,您可能希望使某些参数可选,并在用户不想为它们提供值时使用默认值。这是在默认参数值的帮助下完成的。您可以通过在函数定义中的参数名称附加赋值运算符(=
)后跟默认值来指定参数的默认参数值。
请注意,默认参数值应该是常量。更准确地说,默认参数值应该是不可变的 - 这将在后面的章节中详细解释。现在,请记住这一点。
示例(另存为function_default.py
):
def say(message, times=1):
print(message * times)
say('Hello')
say('World', 5)
输出:
$ python function_default.py
Hello
WorldWorldWorldWorldWorld
这个怎么运作
名为的函数say
用于按指定的次数打印字符串。如果我们不提供值,则默认情况下,字符串只打印一次。我们通过为参数指定默认参数值1
来实现此目的times
。
在第一次使用中say
,我们只提供字符串,并打印一次字符串。在第二种用法中say
,我们提供了字符串和一个参数,5
声明我们要说 5次字符串消息。
警告
只有那些位于参数列表末尾的参数才能被赋予默认参数值,即您不能在参数之前使用默认参数值的参数,而不能在函数的参数列表中使用默认参数值。
这是因为值按位置分配给参数。例如,
def func(a, b=5)
是有效的,但是def func(a=5, b)
是不是有效。
关键字参数
如果你有一些带有许多参数的函数并且你只想指定其中的一些参数,那么你可以通过命名它们来为这些参数赋值 - 这叫做关键字参数 - 我们使用名称(关键字)而不是位置(我们使用一直在使用)来指定函数的参数。
有两个优点 - 一个,使用函数更容易,因为我们不需要担心参数的顺序。第二,只要其他参数具有默认参数值,我们就可以只为那些我们想要的参数赋值。
示例(另存为function_keyword.py
):
def func(a, b=5, c=10):
print('a is', a, 'and b is', b, 'and c is', c)
func(3, 7)
func(25, c=24)
func(c=50, a=100)
输出:
$ python function_keyword.py
a is 3 and b is 7 and c is 10
a is 25 and b is 5 and c is 24
a is 100 and b is 5 and c is 50
这个怎么运作
名为的函数func
有一个没有默认参数值的参数,后跟两个带默认参数值的参数。
在第一次使用中,func(3, 7)
参数a
获取值3
,参数b
获取值7
并c
获取默认值10
。
在第二种用法中func(25, c=24)
,a
由于参数的位置,变量的值为25。然后,参数c
获取24
由于命名的值,即关键字参数。变量b
的默认值为5
。
在第三种用法中func(c=50, a=100)
,我们对所有指定值使用关键字参数。请注意,即使之前在函数定义中定义了参数,我们也会c
在此之前指定参数的值。a
a
c
VarArgs参数
有时你可能希望定义,可以采取一个函数的任何数量的参数,即VAR的iable数ARG uments,这可以通过使用星星来实现(另存为function_varargs.py
):
def total(a=5, *numbers, **phonebook):
print('a', a)
#iterate through all the items in tuple
for single_item in numbers:
print('single_item', single_item)
#iterate through all the items in dictionary
for first_part, second_part in phonebook.items():
print(first_part,second_part)
total(10,1,2,3,Jack=1123,John=2231,Inge=1560)
输出:
$ python function_varargs.py
a 10
single_item 1
single_item 2
single_item 3
Inge 1560
John 2231
Jack 1123
这个怎么运作
当我们声明一个星号参数,例如*param
,那个从该点到结尾的所有位置参数都被收集为一个名为'param'的元组。
类似地,当我们声明一个双星参数,例如**param
,那个从该点到结尾的所有关键字参数都被收集为一个名为'param'的字典。
我们将在后面的章节中探讨元组和字典。
该return
声明
该return
语句用于从函数返回,即退出函数。我们也可以选择从函数中返回一个值。
示例(另存为function_return.py
):
def maximum(x, y):
if x > y:
return x
elif x == y:
return 'The numbers are equal'
else:
return y
print(maximum(2, 3))
输出:
$ python function_return.py
3
这个怎么运作
该maximum
函数返回参数的最大值,在这种情况下是提供给函数的数字。它使用一个简单的if..else
语句来查找更大的值,然后返回该值。
请注意,return
没有值的语句相当于return None
。None
是Python中的一种特殊类型,代表虚无。例如,它用于表示如果变量的值为,则变量没有值None
。
return None
除非您编写了自己的return
语句,否则每个函数都隐式包含一个语句。您可以通过运行print(some_function())
函数some_function
不使用return
语句来查看此内容,例如:
def some_function():
pass
该pass
语句在Python中用于表示一个空的语句块。
提示:有一个内置函数
max
,它已经实现了'find maximum'功能,所以尽可能使用这个内置函数。
文档字符串
Python有一个漂亮的功能,称为文档字符串,通常由其较短的名称docstrings引用。DocStrings是您应该使用的重要工具,因为它有助于更好地记录程序并使其更易于理解。令人惊讶的是,当程序实际运行时,我们甚至可以从函数中获取文档字符串!
示例(另存为function_docstring.py
):
def print_max(x, y):
'''Prints the maximum of two numbers.
The two values must be integers.'''
# convert to integers, if possible
x = int(x)
y = int(y)
if x > y:
print(x, 'is maximum')
else:
print(y, 'is maximum')
print_max(3, 5)
print(print_max.__doc__)
输出:
$ python function_docstring.py
5 is maximum
Prints the maximum of two numbers.
The two values must be integers.
这个怎么运作
函数的第一个逻辑行上的字符串是该函数的文档字符串。请注意,DocStrings也适用于我们将在相应章节中学习的模块和类。
docstring遵循的约定是多行字符串,其中第一行以大写字母开头,以点结尾。然后第二行是空白,然后是从第三行开始的任何详细说明。你是强烈建议遵循这一惯例所有的文档字符串为您的所有非普通功能。
我们可以使用print_max
函数的__doc__
(注意双下划线)属性(属于名称)来访问函数的docstring 。请记住,Python将所有内容视为对象,包括函数。我们将在关于类的章节中了解有关对象的更多信息。
如果您已经help()
在Python中使用过,那么您已经看过了docstrings的用法!它的作用是获取该__doc__
函数的属性并以一种整洁的方式为您显示它。您可以尝试上面的功能 - 只需包含help(print_max)
在您的程序中。记得q
按键退出help
。
自动化工具可以通过这种方式从程序中检索文档。因此,我强烈建议您将docstrings用于您编写的任何非平凡函数。pydoc
Python发行版附带的命令与help()
使用docstrings 类似。
功能注释
函数注释是关于用户定义函数使用的类型的完全可选元数据信息
注释__annotations__
作为字典存储在函数的属性中,对函数的任何其他部分没有影响。参数注释由参数名称后面的冒号定义,后跟一个表达式,用于评估注释的值。返回值注释由->
参数列表和表示def
语句结尾的冒号之间的文字,后跟表达式定义。以下示例具有位置参数,关键字参数和注释的返回值
注释可以是关键字,也可以是字符串,这样可以更好的表达出对参数所要做出的描述
使用Python计算斐波那契数列
Lambda表达式
可以使用lambda
关键字创建小的匿名函数。此函数返回其两个参数的总和:。Lambda函数可以在需要函数对象的任何地方使用。它们在语法上限于单个表达式。从语义上讲,它们只是正常函数定义的语法糖。与嵌套函数定义一样,lambda函数可以引用包含范围的变量:lambda a, b: a+b
释义:也就是说lambda表达式是一个可以定义单行运算方法的函数关键字其中 :前面是定义此函数的参数 :后面是此函数的具体算法,但只能有一行。例:
上面的示例使用lambda表达式返回一个函数。另一个用途是传递一个小函数作为参数:
Intermezzo:编码风格
现在您要编写更长,更复杂的Python,现在是讨论编码风格的好时机。大多数语言都可以用不同的风格编写(或更简洁,格式化); 有些比其他人更具可读性。让其他人轻松阅读您的代码总是一个好主意,采用一种好的编码风格对此有很大帮助。
对于Python, PEP 8已成为大多数项目坚持的风格指南; 它促进了一种非常易读且令人赏心悦目的编码风格。每个Python开发人员都应该在某个时候阅读它; 以下是为您提取的最重要的要点:
-
使用4空格缩进,没有标签。
4个空格是小压痕(允许更大的嵌套深度)和大压痕(更容易阅读)之间的良好折衷。标签引入混淆,最好省略。
-
换行,使其不超过79个字符。
这有助于用户使用小型显示器,并且可以在较大的显示器上并排放置多个代码文件。
-
使用空行分隔函数和类,以及函数内的较大代码块。
-
如果可能,将评论放在他们自己的一行上。
-
使用docstrings。
-
在操作符周围和逗号后面使用空格,但不能直接在包围结构中使用:。
a = f(1, 2) + g(3, 4)
-
一致地命名您的类和函数; 约定
CamelCase
用于类和lower_case_with_underscores
函数和方法。始终使用self
第一个方法参数的名称(有关类和方法的更多信息,请参阅类的初步查看)。 -
如果您的代码旨在用于国际环境,请不要使用花哨的编码。Python的默认值,UTF-8甚至纯ASCII在任何情况下都能最好地工作。
-
同样,如果只有最轻微的机会,说不同语言的人会阅读或维护代码,请不要在标识符中使用非ASCII字符。
摘要
我们已经看到了功能的许多方面,但请注意,我们仍然没有涵盖它们的所有方面。但是,我们已经涵盖了日常用于Python功能的大部分内容。
接下来,我们将看到如何使用以及创建Python模块。