下面引用一段python3.8中dataclass源代码
def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
unsafe_hash=False, frozen=False):
"""Returns the same class as was passed in, with dunder methods
added based on the fields defined in the class.
Examines PEP 526 __annotations__ to determine fields.
If init is true, an __init__() method is added to the class. If
repr is true, a __repr__() method is added. If order is true, rich
comparison dunder methods are added. If unsafe_hash is true, a
__hash__() method function is added. If frozen is true, fields may
not be assigned to after instance creation.
"""
def wrap(cls):
return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
# See if we're being called as @dataclass or @dataclass().
if cls is None:
# We're called with parens.
return wrap
# We're called as @dataclass without parens.
return wrap(cls)
我们可以发现在函数参数中出现了/和*号,那这两个符号分别代表什么意思呢
参数*
*号作为一个函数参数出现在函数中,表示的是在*号之后的参数在调用时必须用kwargs的方式指定命名调用。
例如这样一个函数
def test(a, b):
pass
我们在调用的时候可以有指定和非指定的方式
test(1, 2)
test(a=1, b=2)
但如果加入了*后
def test(*, a, b):
pass
我们用非指定的方式传参就会报错
test(1, 2)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: test() takes 0 positional arguments but 2 were given
而这种限制只在于*之后的参数,比如下面这个例子就不会报错
def test(a, *, b):
pass
test(1, b=2)
参数/
/号的作用则是表示在/之前的参数都必须为位置参数,而不能用指定命名传入
我们结合*号一起
def test1(a, b, /, *, c, d):
pass
全指定的方式调用就会发现/不允许用指定方式传参
test1(a=1,b=2,c=3,d=4)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: test1() got some positional-only arguments passed as keyword arguments: 'a, b'