Search code examples
pythonsignature

What does the asterisk * mean as the first argument in the signature of a function/class/method?


I am currently trying to understand the Tensorforce library . I keep stumbling across a signature in the form:

class tensorforce.core.layers.Dense(*, size, bias=True, activation='tanh', dropout=0.0, initialization_scale=1.0, vars_trainable=True, l2_regularization=None, name=None, input_spec=None)

Tensorforce Dense Layer

What does it mean if the asterisk * is at the very beginning and how can I instantiate such a class, or can you do that at all?

An instantiation in the form

from tensorforce.core.layers import Dense
d = Dense(4)

fails with the error message

Traceback (most recent call last):

  File "<ipython-input-6-df27ca99113e>", line 1, in <module>
    Dense(4)

TypeError: __init__() takes 1 positional argument but 2 were given

Solution

  • Any arguments specified after the * "argument" (so in this case, all of them) are keyword-only arguments. They can only be supplied by keyword, rather than positionally; this means your example should be:

    from tensorforce.core.layers import Dense
    d = Dense(size=4)
    

    That error message you got is not terribly intuitive, is it? This is a consequence of the fact that in Python, an object's method is essentially a function that automatically receives the object itself as the first argument (which is why you normally write self in a method definition, but don't supply it when calling the method).

    In this case, the __init__ method takes one and exactly one positional argument: its own object instance. Since you also provided size positionally, Python complains that it got two arguments—even though you only explicitly gave it one.