I've seen this SO question (this is not a duplicate): Python bare asterisk in function argument
In python-3.x you can add a bare *
to the function arguments, this means that (quote from docs):
Parameters after “*” or “*identifier” are keyword-only parameters and may only be passed used keyword arguments.
Ok, so, I've defined a function:
>>> def f(a, b, *, c=1, d=2, e=3): ... print('Hello, world!') ...
I can pass c
, d
and e
variable values only by specifying keywords:
>>> f(1, 2, 10, 20, 30) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() takes 2 positional arguments but 5 were given >>> f(1, 2, c=10, d=20, e=30) Hello, world!
Questions are:
Some "real-world" examples would help a lot. Thanks in advance.
The asterisk , also called a "star," is used for a number of different purposed in mathematics. The most common usage is to denote multiplication so, for example, . When used as a superscript, the asterisk is commonly voiced " -star." A raised asterisk is used to denote the adjoint. , or sometimes the complex conjugate ...
For arbitrary positional argument, an asterisk (*) is placed before a parameter in function definition which can hold non-keyword variable-length arguments. These arguments will be wrapped up in a tuple. Before the variable number of arguments, zero or more normal arguments may occur.
In Python, the single-asterisk form of *args can be used as a parameter to send a non-keyworded variable-length argument list to functions. It is worth noting that the asterisk ( * ) is the important element here, as the word args is the established conventional idiom, though it is not enforced by the language.
The asterisk (star) operator is used in Python with more than one meaning attached to it. Single asterisk as used in function declaration allows variable number of arguments passed from calling environment. Inside the function it behaves as a tuple.
PEP 3102 explains the rationale pretty clearly: the point is to allow functions to accept various "options" that are essentially orthogonal in nature. Specifying these positionally is awkward both on the defining and calling side, since they don't have any obvious "priority" that would translate into a positional order.
There are lots of example of functions that would benefit from this in various libraries. For instance, the call signature of pandas.read_csv
is:
def parser_f(filepath_or_buffer, sep=sep, dialect=None, compression=None, doublequote=True, escapechar=None, quotechar='"', quoting=csv.QUOTE_MINIMAL, skipinitialspace=False, lineterminator=None, header='infer', index_col=None, names=None, prefix=None, skiprows=None, skipfooter=None, skip_footer=0, na_values=None, na_fvalues=None, true_values=None, false_values=None, delimiter=None, converters=None, dtype=None, usecols=None, engine='c', delim_whitespace=False, as_recarray=False, na_filter=True, compact_ints=False, use_unsigned=False, low_memory=_c_parser_defaults['low_memory'], buffer_lines=None, warn_bad_lines=True, error_bad_lines=True, keep_default_na=True, thousands=None, comment=None, decimal=b'.', parse_dates=False, keep_date_col=False, dayfirst=False, date_parser=None, memory_map=False, nrows=None, iterator=False, chunksize=None, verbose=False, encoding=None, squeeze=False, mangle_dupe_cols=True, tupleize_cols=False, infer_datetime_format=False):
Except for the filepath, most of these are orthogonal options that specify different aspects of how a CSV file is to be parsed. There's no particular reason why they would be passed in any particular order. You'd go nuts keeping track of any positional order for these. It makes more sense to pass them as keywords.
Now, you can see that pandas doesn't actually define them as keyword-only arguments, presumably to maintain compatibility with Python 2. I would imagine that many libraries have refrained from using the syntax for the same reason. I don't know offhand which libraries (if any) have started using it.
ruby
Below expression in python
def f(a, b, *, c=1, d=2, e=3):
is similar to
def f(a,b, options={}) c = options[:c] || 1 d = options[:d] || 2 e = options[:e] || 3 end
in ruby.
Since, python is explicit is better than implicit langauge, it requires *
(splat) operator in parameters.
PS: I never used python, if i am mistaken please correct me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With