Python 简明教程
Python - Functions
Python 函数是一个有组织、可重用的代码块,用于执行单个的、相关的操作。函数为您的应用程序提供了更好的模块化和高度的代码重用。
自上而下的构建处理逻辑方法涉及定义独立的可重用的函数块。Python 函数可以通过传递所需数据(称为 parameters 或 arguments )从任何其他函数调用。被调用的函数会将结果返回给调用环境。
Defining a Python Function
您可以定义自定义函数来提供所需的功能。以下是 Python 中定义函数的简单规则−
-
函数块以关键字 def 开头,后跟函数名称和括号 ()。
-
任何输入参数或参数都应放置在这些括号内。您还可以在这些括号内定义参数。
-
函数的第一条语句可以是可选的语句;函数的文档字符串或文档字符串。
-
每个函数中的代码块以冒号 (:) 开头,并以缩进开头。
-
语句 return [expression] 退出函数,可选择将表达式传递回调用方。不带参数的 return 语句与 return None 相同。
Calling a Python Function
定义函数仅给它一个名称,指定要包含在函数中的参数,并构造代码块。一旦函数的基本结构最终确定,您可以使用函数名本身来调用它。如果函数需要任何参数,则应将其放在括号内传递。如果函数不需要任何参数,则应保留括号为空。
Example to Call a Python Function
以下是调用 printme() 函数的示例−
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print (str)
return;
# Now you can call the function
printme("I'm first call to user defined function!")
printme("Again second call to the same function")
当执行以上代码时,它会生成以下输出 −
I'm first call to user defined function!
Again second call to the same function
Pass by Reference vs Value
在 C 和 C++ 等编程语言中,有两种向函数传递变量的主要方式,即按值调用和按引用调用(也称为按引用传递和按值传递)。然而,我们在 Python 中向函数传递变量的方式不同于其他方式。
-
call by value − 在调用时将 variable 传递给函数时,实际参数的值会被复制到表示形式参数的变量中。因此,形式参数中的任何更改都不会反映在实际参数中。这种传递变量的方式称为按值调用。
-
call by reference − 在这种传递变量的方式中,会传递对内存中对象的引用。形式参数和实际参数(调用代码中的变量)都引用同一个对象。因此,形式参数中的任何更改都会反映在实际参数中。
Python 使用按引用传递机制。由于 Python 中的变量是对内存中对象的标签或引用,因此用作实际参数的变量和形式参数都真正地引用内存中的同一个对象。我们可以通过在传递之前和之后检查被传递变量的 id() 来验证此事实。
Example
在以下示例中,我们检查变量的 id()。
def testfunction(arg):
print ("ID inside the function:", id(arg))
var = "Hello"
print ("ID before passing:", id(var))
testfunction(var)
如果执行以上代码,将会显示传递之前的 id() 和函数内部的 id()。
ID before passing: 1996838294128
ID inside the function: 1996838294128
行为还取决于传递的对象是可变的还是不可变的。Python 数值对象是不可变的。传递数值对象时,如果该函数更改了形式参数的值,它实际上会创建一个新的内存对象,使原始变量保持不变。
Example
以下示例展示了将不可变对象传递给函数时的行为。
def testfunction(arg):
print ("ID inside the function:", id(arg))
arg = arg + 1
print ("new object after increment", arg, id(arg))
var=10
print ("ID before passing:", id(var))
testfunction(var)
print ("value after function call", var)
它将生成以下 output −
ID before passing: 140719550297160
ID inside the function: 140719550297160
new object after increment 11 140719550297192
value after function call 10
现在让我们将可变对象(例如列表或字典)传递给函数。它也按引用传递,因为传递前后的列表的 id() 相同。但是,如果我们在函数内部修改列表,其全局表示也将反映该更改。
Example
在这里,我们传递一个列表,附加一个新项目,然后查看原始列表对象的内容,我们会发现它已更改。
def testfunction(arg):
print ("Inside function:",arg)
print ("ID inside the function:", id(arg))
arg=arg.append(100)
var=[10, 20, 30, 40]
print ("ID before passing:", id(var))
testfunction(var)
print ("list after function call", var)
它将生成以下 output −
ID before passing: 2716006372544
Inside function: [10, 20, 30, 40]
ID inside the function: 2716006372544
list after function call [10, 20, 30, 40, 100]
Python Function Arguments
函数参数是在调用函数时传递给函数的值或变量。函数的行为通常取决于传递给它的参数。
在定义函数时,您在括号内指定变量列表(称为形式参数)。这些参数充当在调用函数时将传递给该函数的数据的占位符。当调用函数时,必须为每个形式参数提供值。这些称为实际参数。
Example
让我们修改 greetings 函数,并将 name 设置为参数。作为实际参数传递给函数的字符串将在函数内变成 name 变量。
def greetings(name):
"This is docstring of greetings function"
print ("Hello {}".format(name))
return
greetings("Samay")
greetings("Pratima")
greetings("Steven")
此代码将生成以下输出:
Hello Samay
Hello Pratima
Hello Steven
Positional or Required Arguments
必需参数是按正确的位置顺序传递给函数的参数。在这里,函数调用中的参数数量应与函数定义完全匹配,否则代码会给出一个语法错误。
Example
在下面的代码中,我们调用函数 printme(),不带任何参数,这将产生错误。
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print (str)
return;
# Now you can call printme function
printme()
执行上述代码后,将生成以下结果 −
Traceback (most recent call last):
File "test.py", line 11, in <module>
printme();
TypeError: printme() takes exactly 1 argument (0 given)
Keyword Arguments
关键字参数与函数调用相关。当您在函数调用中使用关键字参数时,调用者通过参数名称识别参数。这允许您跳过参数或将它们置于顺序之外,因为 Python 解释器能够使用提供的关键字将值与参数匹配。
Example 1
以下示例展示了如何在 Python 中使用关键字参数。
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print (str)
return;
# Now you can call printme function
printme( str = "My string")
执行上述代码后,将生成以下结果 −
My string
Example 2
以下示例给出了更加清晰的图片。请注意,参数的顺序无关紧要。
# Function definition is here
def printinfo( name, age ):
"This prints a passed info into this function"
print ("Name: ", name)
print ("Age ", age)
return;
# Now you can call printinfo function
printinfo( age=50, name="miki" )
执行上述代码后,将生成以下结果 −
Name: miki
Age 50
Default Arguments
默认参数是指如果在函数调用中未为该参数提供值,则假定该参数的默认值。
Example
以下示例给出了有关默认参数的思路,如果未传递默认年龄,则打印默认年龄:
# Function definition is here
def printinfo( name, age = 35 ):
"This prints a passed info into this function"
print ("Name: ", name)
print ("Age ", age)
return;
# Now you can call printinfo function
printinfo( age=50, name="miki" )
printinfo( name="miki" )
执行上述代码后,将生成以下结果 −
Name: miki
Age 50
Name: miki
Age 35
Positional-only arguments
那些只能通过它们在函数调用中的位置来指定的参数被称为仅限位置的参数。它们是通过在函数的参数列表中所有仅限位置的参数后面放置“/”来定义的。此功能是随着 Python 3.8 的发布而引入的。
使用此类型的参数的好处是,它确保以正确的顺序使用正确的参数来调用函数。仅限位置的参数应作为位置参数传递给函数,而不是关键字参数。
Keyword-only arguments
那些必须在调用函数时按其名称指定的参数称为仅限关键字的参数。它们是通过在函数的参数列表中任何仅限关键字的参数之前放置星号(“*”)来定义的。此类型的参数只能作为关键字参数传递给函数,而不是位置参数。
Arbitrary or Variable-length Arguments
可能需要为某个函数处理比函数定义时指定的参数更多的参数。这些参数称为可变长参数,并且与必需参数和默认参数不同,它们在函数定义中没有名称。
具有非关键词可变参数的函数的语法如下 −
def functionname([formal_args,] *var_args_tuple ):
"function_docstring"
function_suite
return [expression]
一个星号 (*) 放在变量名前面,该变量保存所有非关键词可变参数的值。如果在函数调用期间未指定任何其他参数,则此元组将保持为空。
Example
以下是 Python 可变长参数的一个简单示例。
# Function definition is here
def printinfo( arg1, *vartuple ):
"This prints a variable passed arguments"
print ("Output is: ")
print (arg1)
for var in vartuple:
print (var)
return;
# Now you can call printinfo function
printinfo( 10 )
printinfo( 70, 60, 50 )
执行上述代码后,将生成以下结果 −
Output is:
10
Output is:
70
60
50
在下一章中,我们将详细讨论这些函数参数。
Python Function with Return Value
函数定义中最后一个语句作为 return 关键字表示函数块的结束,并且程序流返回到调用函数。尽管块中最后一个语句之后的缩进减少也意味着返回,但使用显式返回是一种良好的做法。
除了流程控制之外,函数还可向调用函数返回值。已返回表达式的值可以存储在变量中以进行进一步处理。
The Anonymous Functions
当函数不是通过使用 def 关键字以标准方式声明时,这些函数称为匿名函数。相反,它们是使用 lambda 关键字定义的。
-
Lambda 表达式可以获取任意数量的参数,但仅以表达式的形式返回一个值。它们不能包含命令或多个表达式。
-
匿名函数不能直接调用 print,因为 lambda 需要一个表达式
-
Lambda 函数具有自己的本地命名空间,并且除了其参数列表中的那些变量和全局命名空间中的那些变量之外,无法访问其他变量。
-
尽管 lambda 看起来是函数的单行版本,但它们并不等同于 C 或 C++ 中的内联语句,其目的是在调用期间绕过函数堆栈分配以提高性能的原因。
Scope of Variables
程序中的所有变量可能无法在该程序的所有位置访问。这取决于变量的声明位置。
scope of a variable 确定可以在其中访问特定标识符的程序部分。Python 中变量有两个基本范围 −
-
Global variables
-
Local variables
Global vs. Local variables
在函数主体内部定义的变量具有局部范围,而在函数外部定义的变量具有全局范围。
这意味着仅可以在声明它们的函数内访问局部变量,而可以在整个程序体中通过所有函数访问全局变量。当调用函数时,将在其中引入声明的变量。
Example
以下是局部范围和全局范围的一个简单示例 −
total = 0; # This is global variable.
# Function definition is here
def sum( arg1, arg2 ):
# Add both the parameters and return them."
total = arg1 + arg2; # Here total is local variable.
print ("Inside the function local total : ", total)
return total;
# Now you can call sum function
sum( 10, 20 );
print ("Outside the function global total : ", total)
执行上述代码后,将生成以下结果 −
Inside the function local total : 30
Outside the function global total : 0