iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python函数的参数细节
  • 588
分享到

python函数的参数细节

函数细节参数 2023-01-30 22:01:05 588人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

按"指针"传递 python中变量赋值、参数传递都是通过"指针"拷贝的方式进行的。除了按"指针"拷贝,还有一种按值拷贝的方式,关于按值、按指针拷贝的细节,参见按值传递 vs. 按指针传递。 所以在Python中,变量赋值、参数传递,都只是

按"指针"传递

python变量赋值、参数传递都是通过"指针"拷贝的方式进行的。除了按"指针"拷贝,还有一种按值拷贝的方式,关于按值、按指针拷贝的细节,参见按值传递 vs. 按指针传递。

所以在Python中,变量赋值、参数传递,都只是拷贝了源数据的一个地址,而不会拷贝内存中完整的数据对象副本。所以,如果在函数内部修改变量指向的数据对象,会影响函数外部的数据。

例如:

def f(x):
    print(x+3)
a=4
f(a)

在将a赋值给本地变量x的时候,只是拷贝了a目前保存的地址给x,使得x也保存了内存中数据对象4的地址。

如果传递的数据对象是可变数据对象(例如列表),那么在函数内部修改它,会影响函数外部的原始数据对象:

L1=[11,22,33,44]
def f(x):
    x[0] += 1

f(L1)
print(L1)   # 输出:[12, 22, 33, 44]

显然,在函数内部修改x[0]的值,函数外部原始的L1也发生了改变。因为L1赋值给x的时候,只是拷贝了一份L1所指向列表的地址给x,使得x也指向这个列表。

为了避免这种情况,可以新创建一份列表的副本,然后传递给函数参数。

L1=[11,22,33,44]
def f(x):
    x[0] += 1

f(L1[:])
print(L1)   # 输出:[11, 22, 33, 44]

上面传递给函数参数x的是L1[:],它会在内存中创建一个新的列表副本,所以x指向的是这个新的副本列表,修改它不会影响原始的列表L1。

函数参数

Python的函数对参数和返回值方面非常宽松,参数变量可以是任意数据类型,返回值也一样,只需使用变量名代替它们即可。

例如,下面的参数x可以是任意类型的结构,可以是数值、字符串、列表、字典等等类型。返回值语句return同理。

def f(x):
    print(x)
    return x

f(2)
f("haha")

实际上,上面调用函数时是按照参数位置进行传参对本地变量x进行赋值的。除此之外,还可以指定为key=value的方式进行传参。例如:

f(x=2)
f(x="haha")

按位置传参

如果是多个参数,则按从左到右的顺序进行参数变量的赋值:

def f(x,y,z):
    print(x)
    print(y)
    print(z)

f(2,3,4)

调用f(2,3,4)的时候,会按照从左向右的位置方式对本地变量x、y、z赋值:x=2,y=3,z=4

按关键字key/value方式传值

python还支持key=value的方式设置函数调用时的参数,使用key=value的方式赋值时,顺序不重要。这种函数调用时的传值方式称为"关键字传值"。

例如:

def f(x,y,z):
    print(x)
    print(y)
    print(z)
    
f(x=3,y="haha",z=4)

也可以打乱顺序:

f(x=3,z=4,y="haha")

还可以将key=value和位置传参的方式进行混合:

f(3,"haha",z=4)

但混合按位置传参方式的时候,位置参数必须在其它传参方式的前面,不仅此处结合key=value时如此,后文中位置参数结合其它方式传参也都如此:位置参数必须在最前面

例如,下面的传参方式是错的:

f(z=4,3,"haha")

参数默认值

在def或lambda声明函数的时候,可以通过var=default的方式指定参数的默认值。

例如:

def f(x=3):
    print(x)

f(4)
f("haha")
f()

上面的f(4)f("haha")都对函数f()的本地变量x进行了赋值。但是最后一个调用语句f()未赋值,而是使用参数的默认值3。

设置参数默认值时,如果函数有多个参数,则带默认值参数后面必须放在最后面。例如:

# 正确
def f(x,y,z=4)
def f(x,y=1,z=4)

# 错误
def f(x,y=4,z)

只要为参数设置了默认值,那么调用函数的时候,这个参数就是可选的,可有可无的,如果没有,则采用默认值。

def f(x,y=2,z=4):
    print(x)
    print(y)
    print(z)

# 不采用任何默认值
f(2,3,4)

# 采用z的默认值
f(2,3)

# 采用y的默认值
# 此时z必须按key=value的方式传值
f(2,z=5)

# y、z都采用默认值
f(2)

变长参数:*

对于任意长度的参数,可以在def声明的函数中使用*将各位置参数收集到一个元组中。例如:

def f(*args):
    print(args)

f(1,2,3,4)

上面调用f(1,2,3,4)的时候,将所有参数都收集到了一个名为args的元组中。所以上面的函数将输出:

(1, 2, 3, 4)

既然是元组,就可以对参数进行迭代遍历:

def f(*args):
    for arg in args:
        print(arg)

f(1,2,3,4)

必须注意,*是按位置收集参数的。

def f(x,y,*args):
    print(x)
    print(y)
    for arg in args:
        print(arg)

f(1,2,3,4)

按照从左向右的传参规则,首先将1赋值给x,将2赋值给y,然后将剩余所有的位置参数收集到args元组中,所以args=(3,4)

如果*后面还有参数,则调用函数的时候,后面的参数必须使用key=value的方式传递,否则会收集到元组中,从而导致参数缺少的问题:

def f(x,*args,y):
    print(x)
    print(y)
    for arg in args:
        print(arg)

# 正确
f(1,3,4,y=2)

# 错误
f(1,2,3,4)

上面调用f(1,3,4,y=2)的时候,会按照位置参数对x赋值为1,然后将所有位置参数收集到元组args中,因为y=2是非位置参数传值方式,所以args=(3,4)

如果为上面的y设置默认值:

def f(x,*args,y=2)

那么f(1,2,3,4)会将(2,3,4)都收集到元组args中,然后y采用默认值2。

变长参数:**

除了可以使用*将位置参数收集到元组中,还可以使用**key=value格式的参数收集到字典中。

例如:

def f(x,**args):
    print(x)
    print(args)

f(1,a=11,b=22,c=33,d=44)

上面首先按位置传参的方式赋值x=1,然后将剩余的所有key=value参数收集到名为args的字典中。所以,args字典的内容为:

{'a': 11, 'b': 22, 'c': 33, 'd': 44}

既然是将参数收集到字典中,就可以使用字典类的工具操作这个字典。例如,遍历字典。

**后面不能出现任何其它类型的参数。例如,下面的都是错误的def定义方式:

def f(x,**args,y)
def f(x,**args,y=3)
def f(x,**args,*t)

只能将位置参数或者*的收集放在**的前面。

def f(x,y,**args)
def f(x,*args1,**args2)

函数调用时的*和**

除了在def定义函数时,参数中可以使用***收集参数,在函数调用的时候也可以使用***分别解包元组(列表或其它对象)、字典。一定要注意区分函数定义和函数调用时的***,它们的用法是不通用的。

例如,解包元组:

def f(a,b,c,d):
    print(a)
    print(b)
    print(c)
    print(d)

T=(1,2,3,4)
f(*T)

*除了可以解包元组,还可以解包其它可迭代对象,例如列表。甚至是字典也能解包,只不过*解包的字典得到的是key组成的参数列表,和value无关:

D=dict(a=11,b=22,c=33,d=44)
f(*D)

# 输出:
a
b
c
d

**解包的字典则是key=value组成的参数列表。以下是函数调用时使用**进行解包,字典D中的key名称必须和def中定义的参数名称相同:

def f(a,b,c,d):
    print(a)
    print(b)
    print(c)
    print(d)

D=dict(a=11,b=22,c=33,d=44)
f(**D)

# 输出:
11
22
33
44

在函数调用时,可以混合位置参数、关键字参数、*解包参数、**解包参数。用法非常的灵活:

def f(a,b,c,d):
    print(a)
    print(b)
    print(c)
    print(d)

f(*(1,2),**{'d':4,'c':3})

f(1,*(2,3),**{'d':4})

f(1,c=3,*(2,),**{'d':4})

f(1,*(2,3),d=4)

f(1,*(2,),c=3,**{'d':4})

上面调用函数时的效果都等同于f(1,2,3,4)

keyWord-only参数形式

keyword-only的参数传值方式表示def中如果使用了*,那么在调用函数时,它后面的参数必须只能使用关键字传值。其实在前面的内容中已经出现过几次与之相关的说明。

另外注意,*才是keyword-only开关,**不是,虽然**也有自己的一些语法限制:任意类型的参数定义都必须在**之前,包括keyword-only类型的参数。这个前面已经解释过了。

例如:

def f(a,*b,c):
    print(a,b,c)

按照keyword-only的规则,被*b收集的位置参数不包括c,这个c必须只能使用关键字的方式传值,否则就被当作位置参数被收集到元组b中。

# 正确
f(1,2,3,c=4)

# 错误
f(1,2,3,4)

# 错误
f(1,c=4,2,3)

其中最后一个错误和如何def的定义无关,而是函数调用时的语法错误,前面已经解释过:位置参数必须放在最前面。

还可以直接使用*而非*args的方式,这表示不收集任何参数,但却要求它后面的参数必须按照关键字传值的方式

def f(a,*,b,c):
    print(a,b,c)

以下是正确和错误的调用方式示例:

# 正确
f(1,b=2,c=3)
f(1,c=3,b=2)
f(b=2,c=3,a=1)

# 错误
f(1,2,3)
f(1,2,c=3)
f(1,b=2,3)

不过,keyword-only后面的参数可以使用参数默认值。

def f(a,*,b,c=3)

那么c是可选的,但如果给定,则必须按关键字方式传值。

参数定义和参数传值的规则

对于函数定义中的参数,有3种方式:普通位置参数、*开启的keyword-only参数、**args收集参数。它们之间的规则是:

  • **args必须在最后面
  • **args后面可以是普通参数,但是函数调用传值时,它后面的参数必须按照关键字的方式指定

所以,函数定义时参数的通用形式为:其中c和d必须使用关键字传值方式

def f(a,b,  *,c,d,  **dicts)
def f(a,b,  *args,c,d,  **dicts)

对于函数调用中的参数,有:普通位置参数、关键字参数、*解包参数、**解包参数。它们之间的规则时:

  • 普通位置参数必须在最前面
  • **解包必须在最后面
  • 关键字参数和*解包参数只要求在上述两种参数形式中间,顺序可以随意

所以,函数调用时的传参形式为:

f(a,b,c,  *(d,e,f),g=1,h=2,  **dict(j=3,k=4))
f(a,b,c,  d=1,e=2,*(f,g,h),  **dict(j=3,k=4))

例如:

def f(a,*b,c,**d):
    print(a,b,c,d)

f(1,  2,3,  c=4,  x=5,y=6)
f(1,  c=4,*(2,3),  **dict(x=5,y=6))
f(1,  *(2,3),c=4,  **dict(x=5,y=6))
f(1,  *(2,3),      **dict(c=4,x=5,y=6))
f(1,  2,3,         **dict(c=4,x=5,y=6))

函数注解(annotations)

python函数有一个名为__annotations__的属性(可以使用dir(Func_Name)来查看)。它表示函数的注解。

函数的注解使得参数变得更规范、更通用,它有点类似于强调数据类型。但它们仅仅只是注解,只是给人看,用来起提示作用的,不会对实际的调用有任何影响

例如,下面是没有给注解的函数参数,也就是平时见到的参数方式:

def myfunc(a,b,c):
    return a+b+c

myfunc(1,2,3)

函数的注解分两种:参数注解和返回值注解。

  • 参数注解:定义在各参数名之后,使用冒号分隔参数和参数的注解
  • 返回值注解:定义在参数列表之后,冒号之前,使用瘦箭头->分隔

例如:

def myfunc(a:'string',b:[1,5],c:int)->int:
    return a+b+c

print( myfunc(1,2,3) )
print( myfunc("a","b","c") )

虽然上面的函数注解提示了参数a是一个字符串,b是一个列表,c是一个int类型的数据,以及返回值是一个int类型的值,但在函数调用的时候,这些"强调"并没有发生影响,只不过在使用该函数的时候,如果使用IDE编写代码,会有代码提示。

可以通过函数的__annotations__属性查看函数的注解:

print(myfunc.__annotations__)

输出:

{'a': 'string', 'b': [1, 5], 'c': <class 'int'>, 'return': <class 'int'>}

可以只对其中一个或多个参数进行注解。

如果使用了注解,还要设置参数的默认值,则默认值需要在注解的后面。例如:

def f(a:'string'=4):

函数注解只对def语句有效,对lambda无效,因为lambda已经限制了函数的定义方式。

--结束END--

本文标题: python函数的参数细节

本文链接: https://www.lsjlt.com/news/180182.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python函数的参数细节
    按"指针"传递 python中变量赋值、参数传递都是通过"指针"拷贝的方式进行的。除了按"指针"拷贝,还有一种按值拷贝的方式,关于按值、按指针拷贝的细节,参见按值传递 vs. 按指针传递。 所以在python中,变量赋值、参数传递,都只是...
    99+
    2023-01-30
    函数 细节 参数
  • python函数的参数
    书写一个函数def  power(x):    return x * x对于power(x)函数,参数x就是一个位置参数,当我们调用power(x)函数时,必须传入有且仅有一个参数xpower(5)power()也是内置函数,用法power...
    99+
    2023-01-31
    函数 参数 python
  • Python的函数参数
    前言 python中 函数的参数可以分为两大类形参和实参~ def func(x, y): # x, y 就是形参 print(x, y) func(2, 3) # 2, 3 就是实参 - 形参 形参(...
    99+
    2023-01-31
    函数 参数 Python
  • Python 函数的参数
    1.1   函数的参数1.1.1   位置参数>>> def power(x, n):...    s = 1...    while n > 0:...        n = n - 1...        s =...
    99+
    2023-01-31
    函数 参数 Python
  • python函数参数
    #没有参数a = 123 def xy(): print(a) xy() #执行结果123#一个参数 def xy(a): print(a) xy('nihao') #执行结果nihao#多个参数 def xy(a1,a...
    99+
    2023-01-30
    函数 参数 python
  • 函数参数python
    函数中的默认参数,调用的时候可以给参数 赋值,也可以使用默认值 修改add函数如下 add()函数第一个参数没有默认值,第二个函数b默认值是3,在调用函数的时候,只赋予了函数实际参数为2, 也就是说该实际参数是2赋值给a,a+b后函数执行...
    99+
    2023-01-31
    函数 参数 python
  • Golang函数的函数类型使用细节探讨
    Golang作为一种现代的编程语言,其在语言设计上具有一些独特的特征,其中最突出的是支持函数类型。函数类型是指一个函数本身可以作为一个参数,或者可以返回另一个函数。这种特征为Golang提供了更加灵活和多样化的编程方式。在本文中,我们将深入...
    99+
    2023-05-16
    Golang 函数类型 使用细节探讨
  • Python 函数 —— 定义,参数,参
    函数函数    数学定义:y = f(x), y是x的函数,x是自变量。 y = f(x0,x1,x2,...,xn)    python函数:        - 由 若干语句组成的语句块、函数名称、参数列表 构成,它是组织代码的最小单元 ...
    99+
    2023-01-31
    函数 定义 参数
  • Python函数的参数浅析
    这篇文章主要介绍“Python函数的参数浅析”,在日常操作中,相信很多人在Python函数的参数浅析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python函数的参数浅析”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-15
  • Python中的函数参数(位置参数、默认参数、可变参数)
    目录一、位置参数二、默认参数三、可变参数四、关键字参数五、命名关键字参数六、各种参数之间的组合函数的参数:Python中函数定义非常简单,由于函数参数的存在,使函数变得非常灵活应用广...
    99+
    2024-04-02
  • Python 函数调用&定义函数&函数参
    一.函数调用 在python中内置了很多函数,我们可以直接调用 。想要调用函数首先要知道函数的名称及包含的参数,还可以通过查看python官方的文档:https://docs.python.org/3/library/functions....
    99+
    2023-01-30
    函数 定义 Python
  • python中函数的参数详解
    目录一、参数的定义1、函数的参数在哪里定义2、带参数的函数调用:二、参数分类1、根据实参进行分类1.1、位置参数(未命名参数)1.2、关键字参数(命名参数)2、根据形参进行分类2.1...
    99+
    2024-04-02
  • python函数的参数形式[]1]
    def cheeseshop(kind,*arguments,**keywords):     print("-- Do you have any",kind,"")     print("-- I'm sorry, we're all o...
    99+
    2023-01-31
    函数 形式 参数
  • Python函数参数(补充)
      最近看了几篇文章,介绍函数传参数的,下面一一介绍,希望对你理解Python有帮助。(一)python中函数的传参问题        前段时间有写了一篇博文介绍了函数参数,其中提到了函数参数的传值方式,其中提到,不可变参数是“通过值”进行...
    99+
    2023-01-31
    函数 参数 Python
  • python基础之 函数的参数
      一、形参和实参是什么  函数的参数分为形式参数和实际参数,简称形参和实参:  形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。  def func(x,y): #x和y为形参  print(x,y) ...
    99+
    2023-06-01
  • Python有哪些函数参数
    本篇内容介绍了“Python有哪些函数参数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、函数参数匹配表语法位置解释func(value)...
    99+
    2023-06-02
  • 函数的参数
    一、位置参数 1 def func(a,b,c): 2 print(a) 3 print(b) 4 print(c) 5 func(1,2,3) 6 func(1,2)#报错 7 func(1,2,3,4)#报错...
    99+
    2023-01-30
    函数 参数
  • python函数中带*及**参数
        python在定义函数的时候,不仅可以设置普通的形参:如def fun(arr1, arr2 = '我是2号参数'):  #arr1为必传参数,arr2可以不用    另外还可以传入两种特殊的参数:带*或**的参数。这两类形式的参数...
    99+
    2023-01-31
    中带 函数 参数
  • 深入了解python的函数参数
    目录位置参数默认参数关键字参数多值参数:总结 位置参数 这是一个求等差数列和的函数,使用必需要传入一个参数n,这就是位置参数 def sum(n): sum=0 ...
    99+
    2024-04-02
  • python怎么遍历函数的参数
    在python中使用inspect模块对函数的参数进行遍历,具体方法如下:import inspect #导入inspect模块def f(a,b,c):argspec=inspect.getargvalues(inspect.curren...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作