Skip to main content

Call functions and create objects by easily assigning values of keyword arguments from some object's attributes of or items from some dictionary.

Project description

CallArgs

Call functions and create objects by easily assigning values of keyword arguments from some object's attributes of or items from some dictionary.

Content

  1. Usage
  2. Variable keyword arguments
  3. Extra arguments
  4. Extending the package's functionality

Usage

When calling a function f with keyword arguments contained in a dictionary d, one can do something like this:

result = f(a=d["a"], b=d["b"],...)

or simply unpack d:

result = f(**d)

Similarly, using attributes of object obj, one can do

result = f(a=obj.a, b=obj.b,...)

or simply unpack d:

result = f(**vars(d))

In both of these cases, the first approach can get tedious if there are many arguments and/or when adding new ones, while the second approach is problematic if a dictionary/object has some items/attributes that f does not accept (which is almost always the case with objects' attributes).

Instead, the above calls can be done like this:

from call_args import call_args_dict
result = call_args_dict(f, d)

or

from call_args import call_args_attr
result = call_args_attr(f, obj)

This can be useful in cases when a dictionary or an object exists specifically for the use with the given callable. For example, when using with command-line arguments:

parser = argparse.ArgumentParser(
    prog=splitext(basename(sys.argv[0]))[0],
    description=sys.modules[__name__].__doc__,
)
...
args = parser.parse_args()
call_args_attr(ClassThatDoesTheJob, args).run()

The call_args_* functions filter out the values that f would not understand, as well as all the private ones (those with names starting with underscore _).

Variable keyword arguments

If the callable allows variable keyword arguments, then the whole source will be used. This means that

def f(**kwargs):
    ...

result1 = call_args_dict(f, d)
result2 = call_args_attr(f, obj)

is mostly equivalent to

def f(**kwargs):
    ...

result1 = f(**d)
result2 = f(**vars(obj))

However, there is still a difference: even in this case, call_args_* functions will not assign values to private arguments, which means that all the items from d and attributes from obj with names starting with an underscore _ will be omitted.

Also, in the case of an object - which might have methods - filtering of names is still useful, as those won't be unpacked (unless the callable expects attributes with exactly those names).

Extra arguments

The calls presented above can accept extra arguments. For example,

def f(a=17, b=19, c=23):
    print(a, b, c)

data = {"b": "29", "c": 31, "d": 37}
call_args_dict(f, data, c=41)

will print 17 29 41 because:

  • a is not defined in data nor among keyword arguments of call_args_dict, so it retains its default value;

  • b is defined only in data, getting its value 29 from there;

  • c is defined in data, but also in keyword arguments of call_args_dict, which are prioritised and thus provide the value 41;

  • d is defined in data, but it is not accepted by f, so call_args_dict silently drops it.

Note that explicitly given keyword arguments are always passed to f. This call:

call_args_dict(f, {"b": "29", "c": 31, "d": 37}, c=41, e=43)

raises a TypeError exception with a message

TypeError: f() got an unexpected keyword argument 'e'

Extending the package's functionality

The work here is done by the class CallArgs. Other "classes" (CallArgsAttr specifically for working with attributes and CallArgsDict for working with dictionaries) are dynamically generated, and they are not classes at all. They are partial objects.

The two functions used above are also dynamically generated.

So, in order to modify or extend the functionality presented above, one only needs to inherit CallArgs, and then recreate these two partials and two functions.

Let us assume that we have a new class NewCallArgs, inherited from CallArgs. These interfaces are created with one of the following calls:

# All four together:
CallArgsAttr, CallArgsDict, call_args_attr, call_args_dict = build_interfaces(
    NewCallArgs,
)
# Only "classes" (partials):
CallArgsAttr, CallArgsDict = build_classes(NewCallArgs)
)
# Only functions:
call_args_attr, call_args_dict = build_functions(NewCallArgs)

The build_* functions accept extra keyword arguments that are passed on to the class constructor, in order to easily modify the default behaviour. Currently, there are two such arguments:

call_args_attr2, call_args_dict2 = build_functions(
    CallArgs, kwargs_as_default=True, skip_private=False,
)

Setting skip_private to False means that the functions will no longer filter out such attributes.

Seeting kwargs_as_default to True changes the meaning of keyword arguments in the newly created functions, so that they are treated as default values instead of overrides of the data. Let us reuse one of the above examples:

def f(a=17, b=19, c=23):
    print(a, b, c)

data = {"b": "29", "c": 31, "d": 37}

# Default behaviour described above:
call_args_dict(f, data, c=41)
# 17 29 41

# Modified behaviour where `c=41` serves as a default value:
call_args_dict2(f, data, c=41)
# 17 29 31  -> 31 comes from `data`
data.pop("c")
call_args_dict2(f, data, c=41)
# 17 29 41

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

call_args-1.0.0.tar.gz (7.6 kB view details)

Uploaded Source

Built Distribution

call_args-1.0.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file call_args-1.0.0.tar.gz.

File metadata

  • Download URL: call_args-1.0.0.tar.gz
  • Upload date:
  • Size: 7.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.23.3

File hashes

Hashes for call_args-1.0.0.tar.gz
Algorithm Hash digest
SHA256 86b8846b1b850644d4d8b7e9697794fe580defe0bdd603fd7e6cba3d89462118
MD5 b55ab0e912608f3bb6c03a1e547d9dbd
BLAKE2b-256 ec92bed3c4103293b38dc071fe95230c329c4194bd7dfe7897b0b714db459d1f

See more details on using hashes here.

File details

Details for the file call_args-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: call_args-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.23.3

File hashes

Hashes for call_args-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b572234590fa2a3ad5da96720f5b44cdd6c8a0ea5a66d99d02a248fbaaa35873
MD5 e27b8f788e6921f197df2a910d0303c2
BLAKE2b-256 a2a982236a59a783803bbc9010d369d4cc726d95ac59afda1f7ac584a89497d9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page