Forced naming of parameters in Python
In Python 3 - Yes, you can specify *
in the argument list.
From docs:
Parameters after “*” or “*identifier” are keyword-only parameters and
may only be passed used keyword arguments.
>>> def foo(pos, *, forcenamed):
... print(pos, forcenamed)
...
>>> foo(pos=10, forcenamed=20)
10 20
>>> foo(10, forcenamed=20)
10 20
>>> foo(10, 20)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 positional argument (2 given)
This can also be combined with **kwargs
:
def foo(pos, *, forcenamed, **kwargs):
To complete example:
def foo(pos, *, forcenamed ):
print(pos, forcenamed)
foo(pos=10, forcenamed=20)
foo(10, forcenamed=20)
# basically you always have to give the value!
foo(10)
output:
Traceback (most recent call last):
File "/Users/brando/anaconda3/envs/metalearning/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3444, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-12-ab74191b3e9e>", line 7, in <module>
foo(10)
TypeError: foo() missing 1 required keyword-only argument: 'forcenamed'
So you are forced to always give the value. If you don't call it you don't have to do anything else named argument forced.
What is the purpose of default arguments for forced keyword arguments in Python?
It doesn't force you to provide the arguments, but it forces you to explicitly provide the keyword argument name when passing it. So function(1, 2, 3)
won't work because you have to specify arg3
explicitly, i.e. function(1, 2, arg3=3)
. Apart from that, the behavior stays the same.
It is commonly used, when the developer realizes that without explicitly stating the name of the keyword argument for the given function can/will confuse the developer who reads the code later.
Variable name to be assigned as argument in a python function
Python functions generally don't "assign variable names", they just return values, and you can do whatever you want with those values.
A value doesn't have a variable name.* Because a value can be stored in five different variables, or it can be stored in things that aren't variables, like the elements of a list. It doesn't care.
So, what you almost certainly want to do is what @spectras suggested in a comment: Get rid of that first parameter, and then store the value in whatever variable you want:
def make_special_tree(arg1, arg2):
tree = Tree()
other_stuff = things(arg1)
modify_tree(tree, other_stuff, arg2)
return tree
# Two different trees with different names
blah = make_special_tree(foo, bar)
yoink = make_special_tree(foo, bar)
# One tree with two names
spam = make_special_tree(foo, bar)
eggs = spam
# A tree with no names at all
cheese = []
cheese.append(make_special_tree(foo, bar))
If you really do want to create a global variable with a specified name, you can do that,** but it's a really bad idea, unless you're trying to do something unusual, like the way collections.namedtuple
acts like a class
statement.
* A value can have a name by having, e.g., a name
attribute. You can even change the definition of the Tree
class to use that name
attribute as part of its output representation. But this still has nothing to do with what variables you store it in.
** The least hacky way is globals()[name] = value
.
Python Decorator to force passing arguments explicitly
If you can modify the function definition, refer to this question.
A minimal decorator to patch existing functions looks like this:
def explicitarguments(f):
def f_new(**kwargs):
return f(**kwargs)
return f_new
What are the conventions for ordering parameters in Python?
There's really no convention for ordering function parameters, except a limitation that positional non-default parameters must go before parameters with defaults and only then keyword parameters, i.e. def func(pos_1, pos_n, pos_1_w_default='default_val', pos_n_w_default='default_val', *args, kw_1, kw_n, kw_1_w_default='default_val', kw_n_w_default='default_val', **kwargs)
.
Usually you define parameters order logically based on their meaning for the function, e.g. if you define a function that does subtraction, it's logical, that minuend should be the first parameter and subtrahend should be second. In this case reverse order is possible, but it's not logical.
Also, if you consider that your function might be used partially, that might affect your decision on parameter ordering.
Most things you need to know about function parameters are in the official tutorial.
P.S. Regarding your particular example with graph function... Considering your function name, it is used for displaying a graph, so a graph
must be provided as argument, otherwise there's nothing to display, so making graph=None
by default doesn't make much sense.
Getting list of parameter names inside python function
Well we don't actually need inspect
here.
>>> func = lambda x, y: (x, y)
>>>
>>> func.__code__.co_argcount
2
>>> func.__code__.co_varnames
('x', 'y')
>>>
>>> def func2(x,y=3):
... print(func2.__code__.co_varnames)
... pass # Other things
...
>>> func2(3,3)
('x', 'y')
>>>
>>> func2.__defaults__
(3,)
For Python 2.5 and older, use func_code
instead of __code__
, and func_defaults
instead of __defaults__
.
Naming parameters the same as the variable passed to them?
The "problem" in this particular case is that the function parameter name will shadow the outer param
variable; i.e. you cannot (implicitly) refer to the global param
anymore because inside your function param
is defined as a local variable.
But, this is really as it should be. Your function should only worry about the parameters it declares locally, not about implicit global variables. Conversely, a caller of a function should not have to worry about anything that goes on inside a function. Naming a variable the same as a parameter to a function is of no consequence to the caller, and should be of no consequence to the function itself.
So, no, there's absolutely no issue here.
Related Topics
Pandas Group by and Find First Non Null Value for All Columns
How to Set the Figure Title and Axes Labels Font Size in Matplotlib
Downloading File to Specified Location with Selenium and Python
Add Sum of Values of Two Lists into New List
Get Raw Post Body in Python Flask Regardless of Content-Type Header
How to Set Default Python Version to Python3 in Ubuntu
Python How to Write to a Binary File
Fastest Way to Take a Screenshot with Python on Windows
Framerate Affect the Speed of the Game
How to Save and Load Numpy.Array() Data Properly
How to Hide the Console Window in a Pyqt App Running on Windows
Comprehension for Flattening a Sequence of Sequences
List() Uses Slightly More Memory Than List Comprehension
Differences Between Numpy.Random and Random.Random in Python
Create PDF from a List of Images
Underscore VS Double Underscore with Variables and Methods
How to Change the Range of the X-Axis with Datetimes in Matplotlib
Parsing a JSON String Which Was Loaded from a CSV Using Pandas