I have a dictionary that I would like to expand to satisfy a
function's agument list. I can used the ** syntax to pass a dictionary,
but
this only works if each key in the dictionary matches an argument.
I cannot pass a dictionary that has more keys than the function has
arguments.
# Example 1 - This works:
# Prints "hello world!"
def foo (arg1='greeting s', arg2='planet', arg3='.'):
print arg1 + ' ' + arg2 + arg3
args = {'arg1':'hello' , 'arg2':'world', 'arg3':'!'}
foo (**args)
# Example 2 - This does not work:
# raises TypeError: foo() got an unexpected keyword argument 'arg4')
def foo (arg1='greeting s', arg2='planet', arg3='.'):
print arg1 + ' ' + arg2 + arg3
args = {'arg1':'hello' , 'arg2':'world', 'arg3':'!', 'arg4':'ignore' }
foo (**args)
As a practical application, I have a project where I have a config file
that defines a large number of keys and values. I read the config
file into a dictionary called "options". I also have an API module with
many
functions that I want to call with arguments taken directly from the
"options" dictionary. The key names in the "options" dictionary match
the argument names of the functions in my API.
# The ugly, brutish way:
options = read_config ("options.conf" )
extract_audio (options['source_video_f ilename'])
compress_audio (options['audio_raw_file name'],
options['audio_compress ed_filename'], options['audio_sample_r ate'],
options['audio_bitrate'])
mux (options['source_video_f ilename'],
options['audio_compress ed_filename'], options['output_video_f ilename'])
I know that the keys in my "options" dictionary match the arguments
of the functions in the API library, so I would like to do this:
options = read_config ("options.conf" )
extract_audio (**options)
compress_audio (**options)
mux (**options)
I created the following function to do what I am describing.
This isn't too bad, but I thought that perhaps there was some
secret Python syntax that will do this for me.
def apply_smart (func, args):
"""This is similar to func(**args), but this won't complain about
extra keys in 'args'. This ignores keys in 'args' that are
not required by 'func'. This passes None to arguments that are
not defined in 'args'. That's fine for arguments with a default
valeue, but
that's a bug for required arguments. I should probably raise a
TypeError.
"""
if hasattr(func,'i m_func'): # Handle case when func is a class
method.
func = func.im_func
argcount = func.func_code. co_argcount
required_args = dict([(k,args.get(k)) for k in
func.func_code. co_varnames[:argcount]])
return func(**required _args)
So, I now I can do this:
options = read_config ("options.conf" )
apply_smart (extract_audio, options)
apply_smart (compress_audio , options)
apply_smart (mux, options)
Neat, but is that the best I can do?
Yours,
Noah 4 3351
Noah a écrit : I have a dictionary that I would like to expand to satisfy a function's agument list. I can used the ** syntax to pass a dictionary, but this only works if each key in the dictionary matches an argument. I cannot pass a dictionary that has more keys than the function has arguments.
If you have control over the API functions declarations, makes them so:
def my_api_func(arg 1='', arg2='whatever' , **kwargs):
code_here
Bruno Desthuilliers a écrit : Noah a écrit : If you have control over the API functions declarations, makes them so: def my_api_func(arg 1='', arg2='whatever' , **kwargs): code_here
Unfortunately I cannot change the API functions.
I should have mentioned that.
Yours,
Noah
Noah wrote: Bruno Desthuilliers a écrit :
Noah a écrit : If you have control over the API functions declarations, makes them so: def my_api_func(arg 1='', arg2='whatever' , **kwargs): code_here
Unfortunately I cannot change the API functions. I should have mentioned that.
Yeps... That what I thought, but you didn't mention it, and it was not
that clear (or it's me being stupid...).
I'm no great expert, but apart from writing a generic decorator for the
API objects and decorating them all with your smart_apply function -
which won't by you much in this case imho -, I don't see a much better
solution...
Some guru around ???
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
On 1 Nov 2005 17:17:00 -0800, "Noah" <no**@noah.or g> wrote: I have a dictionary that I would like to expand to satisfy a function's agument list. I can used the ** syntax to pass a dictionary, but this only works if each key in the dictionary matches an argument. I cannot pass a dictionary that has more keys than the function has arguments.
[...]I created the following function to do what I am describing. This isn't too bad, but I thought that perhaps there was some secret Python syntax that will do this for me.
def apply_smart (func, args): """This is similar to func(**args), but this won't complain about extra keys in 'args'. This ignores keys in 'args' that are not required by 'func'. This passes None to arguments that are not defined in 'args'. That's fine for arguments with a default valeue, but that's a bug for required arguments. I should probably raise a TypeError. """
Ok, so why not do it? ;-) if hasattr(func,'i m_func'): # Handle case when func is a class method. func = func.im_func
skipself = True
else: skipself = False argcount = func.func_code. co_argcount
Make arg list and call with it instead of required_args = dict([(k,args.get(k)) for k in func.func_code .co_varnames[:argcount]]) return func(**required _args)
try:
required_args = [args[k] for k in func.func_code. co_varnames[skipself:argcou nt]]
except KeyError:
raise TypeError, '%s(...) missing arg %r'%(func.func_ name, k)
return func(*required_ args) So, I now I can do this: options = read_config ("options.conf" ) apply_smart (extract_audio, options) apply_smart (compress_audio , options) apply_smart (mux, options)
Neat, but is that the best I can do?
I suppose you could replace your local bindings of extract_audio, compress_audio, and mux
with wrapper functions of the same name that could cache the func and arg names in closure
variables, e.g., using a decorator function (virtually untested)
def call_with_args_ from_dict(func) :
argnames = func.func_code. co_varnames[hasattr(func, 'im_func'):func .func_code.co_a rgcount]
ndefaults = len(func.func_d efaults or ())
if ndefaults:
defnames = argnames[-ndefaults:]
argnames = argnames[:-ndefaults]
else:
defnames = []
def _f(**args):
try:
actualargs = [args[argname] for argname in argnames]
for argname in defnames:
if argname not in args: break
actualargs.appe nd(args[argname])
except KeyError: raise TypeError, '%s(...) missing arg(s) %r'%(
func.func_name, [argname for argname in argnames if argname not in args])
return func(*actualarg s)
_f.func_name = func.func_name
return _f
and then wrap like
extract_audio = call_with_args_ from_dict(extra ct_audio)
or use as a decorator if you are defining the function to be wrapped, e.g.,
@call_with_args _from_dict
def mux(firstarg, second, etc):
...
Regards,
Bengt Richter This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Jack Carter |
last post by:
I have been delegated to produce a tool that has
python embedded in it. The desire is to have a
command line interface that inherits all the python
scripting functionality so people can use the tool
either with a flat commandline entry like you would
a debugger or with a script using scoping, loops and
conditional.
I am going from knowing nothing about python to
almost nothing so the learning curve is rather
|
by: Stefan Behnel |
last post by:
Hi!
I'm trying to do this in Py2.4b1:
-------------------------------
import logging
values = {'test':'bla'}
logging.log(logging.FATAL, 'Test is %(test)s', values)
-------------------------------
|
by: Raymond Hettinger |
last post by:
I would like to get everyone's thoughts on two new dictionary methods:
def count(self, value, qty=1):
try:
self += qty
except KeyError:
self = qty
def appendlist(self, key, *values):
try:
|
by: David Bear |
last post by:
I know there must be a better way to phrase this so google understands, but
I don't know how.. So I'll ask people.
Assume I have a list object called 'alist'.
Is there an easy way to create a dictionary object with the members of
'alist' being the keys in the dictionary, and the value of the keys set to
null?
--
|
by: s99999999s2003 |
last post by:
hi
i have a dictionary defined as
execfunc = { 'key1' : func1 }
to call func1, i simply have to write execfunc .
but if i have several arguments to func1 , like
execfunc = { 'key1' : func1(**args) }
| |
by: Noah |
last post by:
Is there a simple way to get a dictionary of
argument names and their default values for
a method or function? I came up with one solution, but
I feel like Python must have a simpler way.
Python provide a way to get a sequence of
argument names and a different way to get a
sequence of default argument values. Since
default values have to come at the end of an
argument list you can match up the values in the
|
by: 63q2o4i02 |
last post by:
Hi,
I'm writing a hand-written recursive decent parser for SPICE syntax
parsing. In one case I have one function that handles a bunch of
similar cases (you pass the name and the number of tokens you're
looking for). In another case I have a function that handles a
different set of tokens and so it can't use the same arguments as the
first one, and in fact takes no arguments. However, these functions
are semantically similar and are...
|
by: James Harris |
last post by:
Initial issue: read in an arbitrary-length piece of text.
Perceived issue: handle variable-length data
The code below is a suggestion for implementing a variable length
buffer that could be used to read text or handle arrays of arbitrary
length. I don't have the expertise in C of many folks here so I feel
like I'm offering a small furry animal for sacrifice to a big armour
plated one... but will offer it anyway. Please do suggest...
|
by: James Mills |
last post by:
On Fri, Oct 31, 2008 at 8:49 AM, mark floyd <emfloyd2@gmail.comwrote:
Mark, this is correct behavior. You have
3 positional arguments in the function
definition. You _must_ aupply _all_ 3
of them. If you wish for b to be optional,
then you must give it a default value.
def foo(a, b=None, c=None):
print a
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
| |
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |