Professional Documents
Culture Documents
@convert_to("US_Dollars", "income")
def show_me_the_money(name, income):
print(f"{name} : {income}")
Despite this common idiom for argmap, most of the following examples
use the `@argmap(...)` idiom to save space.
Here's an example use of argmap to sum the elements of two of the functions
arguments. The decorated function::
@argmap(sum, "xlist", 2)
def foo(xlist, y, zlist):
return xlist - y + zlist
or::
@argmap(sum, "zlist", 0)
def foo(xlist, y, zlist):
return xlist - y + zlist
# the 2-tuple tells argmap that the map `swap` has 2 inputs/outputs.
@argmap(swap, ("a", "b")):
def foo(a, b, c):
return a / b * c
is equivalent to::
def foo(a, b, c):
a, b = swap(a, b)
return a / b * c
More generally, the applied arguments can be nested tuples of strings or ints.
The syntax `@argmap(some_func, ("a", ("b", "c")))` would expect `some_func` to
accept 2 inputs with the second expected to be a 2-tuple. It should then return
2 outputs with the second a 2-tuple. The returns values would replace input "a"
"b" and "c" respectively. Similarly for `@argmap(some_func, (0, ("b", 2)))`.
Also, note that an index larger than the number of named parameters is allowed
for variadic functions. For example::
def double(a):
return 2 * a
@argmap(double, 3)
def overflow(a, *args):
return a, args
**Try Finally**
For example this map opens a file and then makes sure it is closed::
def open_file(fn):
f = open(fn)
return f, lambda: f.close()
def foo(file):
file, close_file = open_file(file)
try:
print(file.read())
finally:
close_file()
@argmap(open_file, 0, try_finally=True)
def foo(file):
print(file.read())
Here's an example of the try_finally feature used to create a decorator::
def my_closing_decorator(which_arg):
def _opener(path):
if path is None:
path = open(path)
fclose = path.close
else:
# assume `path` handles the closing
fclose = lambda: None
return path, fclose
return argmap(_opener, which_arg, try_finally=True)
@my_closing_decorator("file")
def fancy_reader(file=None):
# this code doesn't need to worry about closing the file
print(file.read())
is equivalent to::
def file_to_lines_wrapped(file):
for line in file.readlines():
yield line
def file_to_lines_wrapper(file):
try:
file = open_file(file)
return file_to_lines_wrapped(file)
finally:
file.close()
def file_to_lines_whoops(file):
file = open_file(file)
file.close()
for line in file.readlines():
yield line
Notes
-----
An object of this class is callable and intended to be used when
defining a decorator. Generally, a decorator takes a function as input
and constructs a function as output. Specifically, an `argmap` object
returns the input function decorated/wrapped so that specified arguments
are mapped (transformed) to new values before the decorated function is called.
As an overview, the argmap object returns a new function with all the
dunder values of the original function (like `__doc__`, `__name__`, etc).
Code for this decorated function is built based on the original function's
signature. It starts by mapping the input arguments to potentially new
values. Then it calls the decorated function with these new values in place
of the indicated arguments that have been mapped. The return value of the
original function is then returned. This new function is the function that
is actually called by the user.
The remaining notes describe the code structure and methods for this
class in broad terms to aid in understanding how to use it.
Other `argmap` methods include `_name` and `_count` which allow internally
generated names to be unique within a python session.
The methods `_flatten` and `_indent` process the nested lists of strings
into properly indented python code ready to be compiled.
See Also
--------
not_implemented_for
open_file
nodes_or_number
random_state
py_random_state
networkx.community.quality.require_partition
require_partition
Fr0