当前位置:   article > 正文

python 函数仅限位置形参 `/`_python 定义的形参只能按固定位置写 怎么办

python 定义的形参只能按固定位置写 怎么办

在python3.8之前,python中有位置参数默认参数可变参数关键字参数。在此,我们先回顾一下,下面先给出两个方法:

def print_name(name):
  print("I am %s" % name)
  
def sum(a, b):
  return a + b 
  • 1
  • 2
  • 3
  • 4
  • 5

在调用这两个方法时,按照参数的位置将参数给进去,这种方式就是位置参数:

print_name("tom")
sum(10, 20)
  • 1
  • 2

接下来,看看默认参数,比如下面有一个 power方法可以计算 xn次方:

def power(x, n):
  return x ** n
  • 1
  • 2

那我们可不可以让它在默认的情况下就计算平方呢?我们可以这么写:

def power(x, n=2):
  return x ** n
  • 1
  • 2

这样在不传入 n的情况下,n就使用默认给的值,如果在调用时给了 n 的值,那么n的值就会被覆盖,这种就属于默认参数

再接着就一起看看,可变参数和关键字参数,有这样一个方法:

def person(name, gender, age=18, city="Beijing", *args, **kwargs):
  print("My name is %s. I'am a %s." % (name, gender))
  print("I'm %d years old. I come from %s" % (age, city))
  print(args)
  for key, value in kwargs:
    print(key, value)    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

*修饰参数就是一个可变参数,函数内部接受到的是一个 tuple,所以我们可以先组装一个 listtuple 再传入; 用 ** 修饰的就是一个关键字参数,函数内部接受到的是一个 dict,同样我们可以先组装一个 dict 再传入。

让我们看看使用的方式:

In [5]: person("tom", "boy", 20, "wuhan", "hello", "hi",hoby="football")                                                                    
My name is tom. I'am a boy.
I'm 20 years old. I come from wuhan
('hello', 'hi')
{'hoby': 'football'}
​
​
In [6]: args = ["hello world", "I'm so happy"]        
In [7]: kwargs = {'fathre':'Bob', 'mother':'lily'}                
In [8]: person("tom", "boy", 20, *args, **kwargs)                       
My name is tom. I'am a boy.
I'm 20 years old. I come from hello world
("I'm so happy",)
{'fathre': 'Bob', 'mother': 'lily'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

然后,在python3.8中加入了仅限位置形参,新增了一个函数形参语法 / 用来指明某些函数形参必须使用仅限位置而非关键字参数的形式。

def f1(a, b, c, d, e, f):
    print(a, b, c, d, e, f)
  • 1
  • 2

在上面 f1() 中,如下几种方式都可以:

f1(10, 20, 30, d=40, e=50, f=60)
f1(10, b=20, c=30, d=40, e=50, f=60)   
f1(10, 20, 30, 40, 50, f=60)
  • 1
  • 2
  • 3

让我们来看看 f2()

def f2(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)
  • 1
  • 2

f2() 中只有第一种是正确的

f(10, b=20, c=30, d=40, e=50, f=60)   # b cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60)           # e must be a keyword argument
  • 1
  • 2

因为在函数中 /* 限制参数的类型,在 / 左边必须是位置参数,在 *右边必须是关键字参数,而在 /*之间的则两者都可以。

这样可以在不需要参数名称时排除掉关键字参数,避免了这种笨拙的调用形式。而且由于在 / 左侧的形参不会被公开为可用关键字,其他形参名仍可在 **kwargs 中使用,就像这样:

>>> def f(a, b, /, **kwargs):
...     print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3)         # a and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}
  • 1
  • 2
  • 3
  • 4
  • 5

参考资料
[1]Python Developer’s Guide: https://www.python.org/dev/peps/pep-0570/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/261362?site
推荐阅读
相关标签
  

闽ICP备14008679号