鱼C论坛

 找回密码
 立即注册
查看: 6968|回复: 9

[技术交流] Python函数的各种参数(含星号参数)

[复制链接]
发表于 2015-12-10 22:25:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 ~风介~ 于 2015-12-10 22:38 编辑
Python中函数的参数有4种形式,分别是:

位置或关键字参数(Positional-or-keyword parameter)
仅位置的参数(Positional-only parameter)
任意数量的位置参数(var-positional parameter)
任意数量的关键字参数(var-keyword parameter)
第一种:位置或关键字参数

这种参数是Python中默认的参数类型,定义这种参数后,可以通过位置参数,或者关键字参数的形式传递参数:
  1. ## 位置或者关键字参数
  2. ## 这个是Python的默认参数类型
  3. ## 示例:arg2提供了默认value
  4. def func(arg1, arg2="World!"):
  5.     print arg1, arg2

  6. ## func可以通过位置参数形式调用
  7. func("Hello", "MitchellChu")

  8. ## 也可以通过关键字参数的形式来调用func
  9. func(arg1="Hello", arg2="World!")

  10. ## 当然,混合的方式也是完全没有问题的
  11. func("Hello", arg2="World!")

  12. ## 不过如果你不能将关键字参数优先于位置参数传递给函数(方法)
  13. ## 这个调用方法是不能接受的,因为优先级不一样.后面会说
  14. func(arg1="Hello", "World!") ## ERROR
复制代码

第二种方式:仅适用位置参数的形式

这种形式在需要将参数传递给函数(方法)时,仅能通过位置参数的传递方式。这种形式对于Python的开发者来说,暂时并没有办法使用。这种形式现在仅存在Python的很多内建的函数上:
  1. ## Positional-only parameter has no syntax to define
  2. ## 虽然无定义方法,但内建的很多函数都是仅接受位置参数的
  3. abs(-3) ## correct
  4. abs(a=3) ## wrong

  5. ## Traceback (most recent call last):
  6. ##   File "<stdin>", line 1, in <module>
  7. ## TypeError: abs() takes no keyword arguments


  8. pow(x=2,y=3)
  9. ## Traceback (most recent call last):
  10. ##   File "<stdin>", line 1, in <module>
  11. ## TypeError: pow() takes no keyword arguments

  12. pow(2,3)
  13. ## 8
复制代码

第三种:任意数量的位置参数(带单个星号参数)

任意数量的位置参数在定义的时候是需要一个星号前缀来表示,在传递参数的时候,可以在原有参数的后面添加任意多个参数,这些参数将会被放在元组内提供给函数(方法):
  1. ## var-positional parameter
  2. ## 定义的时候,我们需要添加单个星号作为前缀
  3. def func(arg1, arg2, *args):
  4.     print arg1, arg2, args

  5. ## 调用的时候,前面两个必须在前面
  6. ## 前两个参数是位置或关键字参数的形式
  7. ## 所以你可以使用这种参数的任一合法的传递方法
  8. func("hello", "Tuple, values is:", 2, 3, 3, 4)

  9. ## Output:
  10. ## hello Tuple, values is: (2, 3, 3, 4)
  11. ## 多余的参数将自动被放入元组中提供给函数使用

  12. ## 如果你需要传递元组给函数
  13. ## 你需要在传递的过程中添加*号
  14. ## 请看下面例子中的输出差异:

  15. func("hello", "Tuple, values is:", (2, 3, 3, 4))

  16. ## Output:
  17. ## hello Tuple, values is: ((2, 3, 3, 4),)

  18. func("hello", "Tuple, values is:", *(2, 3, 3, 4))

  19. ## Output:
  20. ## hello Tuple, values is: (2, 3, 3, 4)
复制代码

第四种:任意数量的关键字参数(带两个星号参数)

任意数量的关键字参数在定义的时候,参数名称前面需要有两个星号(**)作为前缀,这样定义出来的参数,在传递参数的时候,可以在原有的参数后面添加任意多个关键字参数,关键字参数是使用[参数名称=参数值]的形式进行传递:
  1. ## var-keywords parameter
  2. ## 定义的时候,需要两个星号作为前缀
  3. def func(arg1, arg2, **kwargs):
  4.     print arg1, arg2, kwargs

  5. func("hello", "Dict, values is:", x=2, y=3, z=3)
  6. ## hello Dict, values is: {'x': 2, 'y': 3, 'z': 3}
  7. ## 多余的参数将自动被放入字典中提供给函数使用

  8. ## 如果你需要直接传递字典给函数
  9. ## 你需要在传递的过程中添加**
  10. ## 此时如果还有关键字参数应在字典前提供完成
  11. ## 不能在字典后再提供
  12. ## 请看下面例子中的输出差异:

  13. func("hello", "Dict., values is:", **{'x':2, 'y':3, 'z':3,})
  14. ## hello Dict., values is: {'y': 3, 'x': 2, 'z': 3}

  15. func("hello", "Dict., values is:", {'x':2, 'y':3, 'z':3})
  16. ## Traceback (most recent call last):
  17. ##   File "<stdin>", line 1, in <module>
  18. ## TypeError: func() takes exactly 2 arguments (3 given)

  19. func("hello", "Dict., values is:", s=3, **{'x':2, 'y':3, 'z':3,})
  20. ## hello Dict., values is: {'y': 3, 'x': 2, 's': 3, 'z': 3}

  21. ## 提供了重复的参数
  22. func("hello", "Dict., values is:", y=3, **{'x':2, 'y':3, 'z':3,})
  23. ## Traceback (most recent call last):
  24. ##   File "<stdin>", line 1, in <module>
  25. ## TypeError: func() got multiple values for keyword argument 'y'
复制代码



总结:四种参数形式中仅有第二种Python没有提供定义的方法,其他三种在定义的时候也需要注意,定义的时候应该根据Python的解析规律进行定义,其中:

位置或关键字参数应该在最前面,其中,没有默认值的应该在有默认值的参数前面
任意数量位置参数应该放在所有位置或关键字参数的后面
任意数量关键字参数应该放在任意数量位置参数的后面
注意:任意数量位置参数和任意数量关键字参数只能在定义中定义一次。
  1. ## 各种参数的混合使用例子
  2. ## Author: MitchellChu

  3. def func(arg1, arg2='default', *args, **kwargs):
  4.     print "arg1=%s, arg2=%s, args=%s, kwargs=%s" % (arg1, arg2, args, kwargs)


  5. func(1) ## correct
  6. func(1,2) ## correct
  7. func(1,2,3,4) ## correct
  8. func(1,2,3,4,x=1,y=2) ## correct
  9. func(1,2,x=1) ## correct

  10. func(x=1) ## wrong
  11. func(arg1=1) ## correct
  12. func(1,x=1) ## correct

  13. ## 可以将例子保存到parameter.py文件
  14. ## 而后运行python /path/to/parameter.py
复制代码



原文出处:点击打开链接




评分

参与人数 2荣誉 +10 鱼币 +10 贡献 +5 收起 理由
wangguohui + 5 + 5 + 2 感谢楼主无私奉献!
宝贝归来 + 5 + 5 + 3 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-12-31 16:08:57 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-20 13:32:00 | 显示全部楼层
瞅瞅。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-3-28 21:56:49 | 显示全部楼层
没看明白,可能我还没学多少,等以后再回来看,谢谢楼主!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-7-13 20:06:48 | 显示全部楼层
恰好对参数这部分有些疑问,完美解决~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-7-28 16:04:22 | 显示全部楼层
完美!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-29 21:08:45 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-1-11 11:23:00 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-5-30 15:52:31 | 显示全部楼层
感谢楼主无私分享,受益匪浅!
  1. print 'Thank you!'
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 17:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表