Python函数学习:一文即可(python函数详解)
off999 2024-10-11 14:04 26 浏览 0 评论
Python函数解释
16 分钟阅读
了解 Python 函数的概念。如何创建用户定义的函数并使用它们在 Python 中编写模块化程序。
什么是 Python 函数,如何创建和调用?
Python 中的函数是一个独立且可重用的代码块,您可以从程序中的任何位置调用任意次数。它是程序员将大项目拆分为较小模块的重要工具。
它们是程序员必须学会使用的任何编程语言的核心构建块。Python 提供了许多直接使用的内置方法,还允许您定义自定义函数。
-Python 中的函数是代码的逻辑单元,其中包含一系列语句,这些语句缩进到使用“def”关键字给出的名称下。
-函数允许您将大项目逻辑划分为较小的模块。它们使您的代码更易于管理和扩展。
- 编程时,功能可防止您添加重复代码并提高可重用性。
现在让我们快速看看我们还将从本教程中学到什么。
如何创建函数 – 语法
Python 函数的语法如下。
单线功能:
def single_line(): statement
带有帮助文档字符串的 Python 函数:
def fn(arg1, arg2,...):
"""docstring"""
statement1
statement2
嵌套的 Python 函数:
def fn(arg1, arg2,...):
"""docstring"""
statement1
statement2
def fn_new(arg1, arg2,...):
statement1
statement2
...
...
定义声明
在创建第一个 Python 函数之前,请阅读以下说明。
- “def”关键字是在Python中定义函数的语句。
- 使用 def 关键字启动函数,并指定一个名称,后跟冒号 (:) 符号。
- “def”调用创建函数对象并将其分配给给定的名称。
- 您可以进一步将同一函数对象重新分配给其他名称。
- 为函数指定唯一名称,并遵循与命名标识符相同的规则。
- 添加一个有意义的文档字符串来解释函数的作用。但是,这是一个可选步骤。
- 现在,通过添加有效的 Python 语句来启动函数体,每个语句缩进四个空格。
- 您还可以添加语句以在函数末尾返回值。但是,此步骤是可选的。
- 只需按回车键并删除缩进即可结束函数。
- 由于 def 是一个语句,因此您可以在任何可能出现语句的地方使用它,例如嵌套在 if 子句中或其他函数中。
例:
if test:
def test(): # First definition
...
else:
def test(): # Alternate definition
...
...
如何在 Python 中调用函数?
通过使用 def 关键字,您学习了创建函数的蓝图,该函数具有名称、要传递的参数以及具有有效 Python 语句的主体。
下一步是执行它。您可以通过从 Python 脚本、函数内部或直接从 Python shell 调用它来实现。
要调用函数,您需要使用相关参数指定函数名称,仅此而已。
按照下面的示例学习如何在 Python 中调用函数。
函数调用示例
这是一个简单的例子,其中函数“typeOfNum()”具有嵌套函数来决定数字是奇数还是偶数。
def typeOfNum(num): # Function header
# Function body
if num % 2 == 0:
def message():
print("You entered an even number.")
else:
def message():
print("You entered an odd number.")
message()
# End of function
typeOfNum(2) # call the function
typeOfNum(3) # call the function again
Python 中的多态性
- 函数的行为可能因传递给它的参数而异。
- 同一函数可以接受不同对象类型的参数。
- 如果对象找到匹配的接口,函数可以处理它们。
例:
def product(x, y) : return x * y
print(product(4, 9)) # function returns 36
print(product('Python!', 2)) # function returns
# Python!Python!
print(product('Python 2 or 3?', '3')) # TypeError occurs
上面的例子阐明了我们可以将任意两个对象传递给支持 '*' 运算符的 product() 函数。
我们上面解释的概念被称为多态性。您应该记住的一些要点如下。
- Python是一种动态类型语言,这意味着类型与值相关,而不是与变量相关。因此,多态性不受限制地运行。
- 这是Python和其他静态类型语言(如C++或Java)之间的主要区别之一。
- 在 Python 中,编码时不必提及特定的数据类型。
- 但是,如果这样做,则代码将限制为编码时预期的类型。
- 此类代码不允许将来可能需要的其他兼容类型。
- Python 不支持任何形式的函数重载。
函数中的参数
我们经常互换使用术语参数和参数。但是,它们之间略有不同。
参数是函数定义中使用的变量,而参数是我们传递给函数参数的值。
Python 支持将参数传递给函数的不同变体。在我们讨论它们中的每一个之前,您应该阅读以下注释。
- 参数在传递给函数后被分配给局部变量名称。
- 更改函数内参数的值不会影响调用方。
- 如果参数包含可变对象,则在函数中更改它会影响调用方。
- 我们将不可变参数的传递称为按值传递,因为 Python 不允许它们就地更改。
- 可变参数的传递恰好在 Python 中由指针传递,因为它们可能会受到函数内部更改的影响。
示例:不可变与可变
def test1(a, b) :
a = 'Garbage' # 'a' receives an immutable object
b[0] = 'Python' # 'b' receives a list object
# list is mutable
# it can undergo an in place change
def test2(a, b) :
a = 'Garbage 2'
b = 'Python 3' # 'b' now is made to refer to new
# object and therefore argument 'y'
# is not changed
arg1 = 10
arg2 = [1, 2, 3, 4]
test1(arg1, arg2)
print("After executing test 1 =>", arg1, arg2)
test2(arg1, arg2)
print("After executing test 2 =>", arg1, arg2)
执行后,上面的代码打印以下内容。
After executing test 1 => 10 ['Python', 2, 3, 4]
After executing test 2 => 10 ['Python', 2, 3, 4]
如何避免更改可变参数
def test1(a, b) :
a = 'Garbage'
b[0] = 'Python'
arg1 = 10
arg2 = [1, 2, 3, 4]
print("Before test 1 =>", arg1, arg2)
test1(arg1, arg2[:]) # Create an explicit copy of mutable object
# 'y' in the function.
# Now 'b' in test1() refers to a
# different object which was initially a
# copy of 'arg2'
print("After test 1 =>", arg1, arg2)
执行后,上面的代码打印以下内容。
Before test 1 => 10 [1, 2, 3, 4]
After test 1 => 10 [1, 2, 3, 4]
标准参数
标准参数是按照 Python 函数定义中指定的方式传递的参数。这意味着无需更改其顺序,也无需跳过任何顺序。
def fn(value):
print(value)
return
fn()
执行上述代码会引发以下错误,因为我们尚未传递所需的单个参数。
TypeError: fn() missing 1 required positional argument: 'value'
基于关键字的参数
当您为参数赋值(例如 param=value)并将其传递给函数(例如 fn(param=value))时,它会变成关键字参数。
如果将关键字参数传递给函数,则 Python 通过赋值中使用的参数名称来确定它。
def fn(value):
print(value)
return
fn(value=123) # output => 123
fn(value="Python!") # output => Python!
使用关键字参数时,应确保赋值中的名称应与函数定义中的名称匹配。否则,Python 会抛出 TypeError,如下所示。
fn(value1="Python!") # wrong name used in the keyword argument
上述函数调用会导致以下错误。
TypeError: fn() got an unexpected keyword argument 'value1'
具有默认值的参数
Python 函数允许在函数定义中设置参数的默认值。我们将它们称为默认参数。
当调用方未在函数调用中传递这些默认值时,被调用方使用这些默认值。
下面的示例将帮助您清楚地理解默认参数的概念。
def daysInYear(is_leap_year=False):
if not is_leap_year:
print("365 days")
else:
print("366 days")
return
daysInYear()
daysInYear(True)
在这里,参数“is_leap_year”用作默认参数。如果不传递任何值,则假定默认值为 False。
上述代码的输出为:
365 days
366 days
动态参数
您可能会遇到必须将其他参数传递给 Python 函数的情况。我们将它们称为可变长度参数。
Python 的 print() 本身就是支持动态参数的函数的一个例子。
要定义具有变量参数的函数,您需要在参数前面加上星号 (*)。请遵循以下语法。
def fn([std_args,] *var_args_tuple ):
"""docstring"""
function_body
return_statement
查看以下示例以获得更好的清晰度。
def inventory(category, *items):
print("%s [items=%d]:" % (category, len(items)), items)
for item in items:
print("-", item)
return
inventory('Electronics', 'tv', 'lcd', 'ac', 'refrigerator', 'heater')
inventory('Books', 'python', 'java', 'c', 'c++')
上面代码的输出是这样的。
Electronics [items=5]: ('tv', 'lcd', 'ac', 'refrigerator', 'heater')
- tv
- lcd
- ac
- refrigerator
- heater
Books [items=4]: ('python', 'java', 'c', 'c++')
- python
- java
- c
- c++
请注意,您可以选择在函数定义中与可变参数一起使用或不具有正式参数。
您可以选择在调用函数时跳过可变参数。在这种情况下,元组将保持为空。
函数内的局部变量
局部变量仅在代码块(如函数 def)内具有可见性。
它们仅在执行函数时可用。
查看下面的使用局部变量的示例。
def fn(a, b) :
temp = 1
for iter in range(b) :
temp = temp*a
return temp
print(fn(2, 4))
print(temp) # error : can not access 'temp' out of scope of function 'fn'
print(iter) # error : can not access 'iter' out of scope of function 'fn'
在这个例子中,访问函数体外部的局部变量,这会导致 NameError。
函数的局部变量在调用之间不保留值。def 内部使用的名称不会与 def 外部的变量冲突,即使您在其他地方使用了相同的名称也是如此。
在 Python 中,变量赋值可以发生在三个不同的地方。
- locals
- no locals
- globals
函数中的全局变量
global 关键字是 Python 中的语句。它使变量(名称)能够保留位于模块文件顶层的 def 之外的更改。
在单个全局语句中,可以指定一个或多个以逗号分隔的名称。
在函数体内分配或引用时,所有列出的名称都将附加到封闭模块的作用域。
x = 5
y = 55
def fn() :
global x
x = [3, 7]
y = [1, 33, 55]
# a local 'y' is assigned and created here
# whereas, 'x' refers to the global name
fn()
print(x, y)
在上面的代码中,“x”是一个全局变量,它将保留其在函数中所做的任何更改。另一个变量“y”具有局部范围,不会继续更改。
现在让我们看看全局声明的名称在两个不同的 Python 函数中的行为。
foo = 99
def fn1() :
foo = 'new' # new local foo created
def fn2() :
global foo
foo = 'update' # value of global foo changes
在下一个示例中,让我们看看全局如何使用 import 语句。
- mod_global.py:它包含全局定义和一个更改和显示值的函数。
- test1.py:它导入第一个文件并访问全局变量。
- test2.py:它使用 “from” 子句导入第一个文件并访问全局变量。
# mod_global.py
def fn1() :
global x
x = [1,2] ; y = [20, 200]
# a local 'y' is created – availableonly within 'f1'
# 'x' can be accessed anywhere after a call to 'f1'
fn1()
try :
print(x, y) # name 'y' is not defined – error
except Exception as ex:
print('y ->', ex)
print('x ->', x)
# test1.py
import mod_global
print('test1 ->', mod_global.x)
# test2.py
from mod_global import *
print('test2 ->', x)
Python 函数中的一些特点
实际上函数体内查找变量的原则 是就近原则。
#var = 5
def fn1() :
#var = [3, 5, 7, 9]
def fn2() :
#var = (21, 31, 41)
print(var)
fn2()
fn1() # uncomment var assignments one-by-one and check the output
print(var)
取消注释第一个“var”赋值后,输出为:
5
5
接下来,在取消注释第二个“var”赋值后,输出为:
[3, 5, 7, 9]
5
最后,如果我们取消注释最后一个“var”赋值,则结果如下。
(21, 31, 41)
5
函数中的范围查找
Python 函数可以访问所def 语句中的名称。
X = 101 # global scope name - unused
def fn1():
X = 102 # Enclosing def local
def fn2():
print(X) # Reference made in nested def
fn2() # Prints 102: enclosing def local
fn1()
def fn1():
print('In fn1')
X = 100
def fn2():
print('In fn2')
print(X) # Remembers X in enclosing def scope
return fn2 # Return fn2 but don't call it
action = fn1() # Make, return function
action() # Call fn2() now: prints 100
输出如下。
In fn1
In fn2
100
从 Python 函数返回值
在 Python 函数中, “return” 语句来返回一个值。
通常函数返回单个值。Python 允许使用集合类型(例如使用元组或列表)返回多个值。
通过返回元组并将结果赋回调用方中的原始参数名称。
def returnDemo(val1, val2) :
val1 = 'Windows'
val2 = 'OS X'
return val1, val2 # return multiple values in a tuple
var1 = 4
var2 = [2, 4, 6, 8]
print("before return =>", var1, var2)
var1, var2 = returnDemo(var1, var2)
print("after return =>", var1, var2)
上面的代码给出了以下输出。
before return => 4 [2, 4, 6, 8]
after return => Windows OS X
Python函数示例
def getMin(*varArgs) :
min = varArgs[0]
for i in varArgs[1:] :
if i < min :
min = i
return min
min = getMin(21, -11, 17, -23, 6, 5, -89, 4, 9)
print(min)
输出如下。
-89
接下来是递归函数的示例。
def calcFact(num) :
if(num != 1) :
return num * calcFact(num-1)
else :
return 1
print(calcFact(4))
输出如下。
24
Python 函数作为对象
Python一切都是对象,函数也不例外。
可以将函数对象分配给任何其他名称。
def testFunc(a, b) : print('testFunc called')
fn = testFunc
fn(22, 'bb')
输出为:
testFunc called
您甚至可以将函数对象传递给其他函数。
def fn1(a, b) : print('fn1 called')
def fn2(fun, x, y) : fun(x, y)
fn2(fn1, 22, 'bb')
输出为:
fn1 called
您还可以在数据结构中嵌入函数对象。
def fn1(a) : print('fn1', a)
def fn2(a) : print('fn2', a)
listOfFuncs = [(fn1, "First function"), (fn2, "Second function")]
for (f, arg) in listOfFuncs : f(arg)
输出为:
fn1 First function
fn2 Second function
您可以从另一个函数返回函数对象。
def FuncLair(produce) :
def fn1() : print('fn1 called')
def fn2() : print('fn2 called')
def fn3() : print('fn3 called')
if produce == 1 : return fn1
elif produce == 2 : return fn2
else : return fn3
f = FuncLair(2) ; f()
输出为:
fn2 called
函数属性
Python 函数也有属性。
- dir() 函数还列出了用户定义的属性。
def testFunc():
print("I'm just a test function.")
testFunc.attr1 = "Hello"
testFunc.attr2 = 5
testFunc()
print(dir(testFunc))
输出为:
I'm just a test function.
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'attr1', 'attr2']
您可以利用函数属性来存档状态信息,而不是使用任何全局名称或非本地名称。
与非局部变量不同,属性可以在函数本身所在的任何地方访问,甚至可以从其代码外部访问。
总结 – Python 函数
函数是对象,函数可以接收固定,可变参数,函数调用,嵌套函数等,变量作用域。这些知识都需要自己去实践体会。
相关推荐
- 全网第一个讲清楚CPK如何计算的Step by stepExcel和Python同时实现
-
在网上搜索CPK的计算方法,几乎全是照搬教材的公式,在实际工作做作用不大,甚至误导人。比如这个又比如这个:CPK=min((X-LSL/3s),(USL-X/3s))还有这个,很规范的公式,也很清晰很...
- [R语言] R语言快速入门教程(r语言基础操作)
-
本文主要是为了从零开始学习和理解R语言,简要介绍了该语言的最重要部分,以快速入门。主要参考文章:R-TutorialR语言程序的编写需要安装R或RStudio,通常是在RStudio中键入代码。但是R...
- Python第123题:计算直角三角形底边斜边【PythonTip题库300题】
-
1、编程试题:编写一个程序,找出已知面积和高的直角三角形的另外两边(底边及斜边)。定义函数find_missing_sides(),有两个参数:area(面积)和height(高)。在函数内,计算另外...
- Tensor:Pytorch神经网络界的Numpy
-
TensorTensor,它可以是0维、一维以及多维的数组,你可以将它看作为神经网络界的Numpy,它与Numpy相似,二者可以共享内存,且之间的转换非常方便。但它们也不相同,最大的区别就是Numpy...
- python多进程编程(python多进程进程池)
-
forkwindows中是没有fork函数的,一开始直接在Windows中测试,直接报错importosimporttimeret=os.fork()ifret==0:...
- 原来Python的协程有2种实现方式(python协程模型)
-
什么是协程在Python中,协程(Coroutine)是一种轻量级的并发编程方式,可以通过协作式多任务来实现高效的并发执行。协程是一种特殊的生成器函数,通过使用yield关键字来挂起函数的执行...
- ob混淆加密解密,新版大众点评加密解密
-
1目标:新版大众点评接口参数_token加密解密数据获取:所有教育培训机构联系方式获取难点:objs混淆2打开大众点评网站,点击教育全部,打开页面,切换到mobile模式,才能找到接口。打开开发者工具...
- python并发编程-同步锁(python并发和并行)
-
需要注意的点:1.线程抢的是GIL锁,GIL锁相当于执行权限,拿到执行权限后才能拿到互斥锁Lock,其他线程也可以抢到GIL,但如果发现Lock仍然没有被释放则阻塞,即便是拿到执行权限GIL也要立刻...
- 10分钟学会Python基础知识(python基础讲解)
-
看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了。最好还是把代码敲一下。一、函数基础简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运行。...
- Python最常见的170道面试题全解析答案(二)
-
60.请写一个Python逻辑,计算一个文件中的大写字母数量答:withopen(‘A.txt’)asfs:count=0foriinfs.read():ifi.isupper...
- Python 如何通过 threading 模块实现多线程。
-
先熟悉下相关概念多线程是并发编程的一种方式,多线程在CPU密集型任务中无法充分利用多核性能,但在I/O操作(如文件读写、网络请求)等待期间,线程会释放GIL,此时其他线程可以运行。GIL是P...
- Python的设计模式单例模式(python 单例)
-
单例模式,简单的说就是确保只有一个实例,我们知道,通常情况下类其实可以有很多实例,我们这么来保证唯一呢,全局访问。如配置管理、数据库连接池、日志处理器等。classSingleton: ...
- 更安全的加密工具:bcrypt(bcrypt加密在线)
-
作为程序员在开发工作中经常会使用加密算法,比如,密码、敏感数据等。初学者经常使用md5等方式对数据进行加密,但是作为严谨开发的程序员,需要掌握一些相对安全的加密方式,今天给大家介绍下我我在工作中使用到...
- 一篇文章搞懂Python协程(python协程用法)
-
前引之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。按道理来说我们已经算是把cpu的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线...
- Python开发必会的5个线程安全技巧
-
点赞、收藏、加关注,下次找我不迷路一、啥是线程安全?假设你开了一家包子铺,店里有个公共的蒸笼,里面放着刚蒸好的包子。现在有三个顾客同时来拿包子,要是每个人都随便伸手去拿,会不会出现混乱?比如第一个顾...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python字典遍历 (54)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (60)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)