473,806 Members | 2,525 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Checking default arguments


Hi,
I was wondering whether it was possible to find out which parameter
value is being used: the default argument or the user-supplied one.
That is:

def foo(x, y="bar"):
# how to figure out whether the value of y is
# the default argument, or user-supplied?

foo(1, "bar") =user-supplied
foo(1) =default

{}.pop seems to be able to make this dictinction.

I've checked the inspect module, but nothing obvious jumped at me. Any
hints?

Thanks,

ivr
--
"...but it's HDTV -- it's got a better resolution than the real world."
-- Fry, "When aliens attack"
Feb 2 '07 #1
6 1369
On 2007-02-02, Igor V. Rafienko <ig***@ifi.uio. nowrote:
Hi,

I was wondering whether it was possible to find out which
parameter value is being used: the default argument or the
user-supplied one. That is:

def foo(x, y="bar"):
# how to figure out whether the value of y is
# the default argument, or user-supplied?

foo(1, "bar") =user-supplied
foo(1) =default

{}.pop seems to be able to make this dictinction.
You can fake it (this may be how dict.pop work) by not providing
defaults, but using positional arguments.

Here's a silly example, which returns a tuple if the user
supplies the second argument, and a list otherwise.

def foo(x, *args):
if len(args) == 0:
y_provided = True
y = "bar"
else:
y_provided = False
y = args[0]
if y_provided:
return (x, y)
else:
return [x, y]

--
Neil Cerutti
Wonderful bargains for men with 16 and 17 necks --sign at clothing store
Feb 2 '07 #2
Igor V. Rafienko wrote:
I was wondering whether it was possible to find out which parameter
value is being used: the default argument or the user-supplied one.
That is:

def foo(x, y="bar"):
# how to figure out whether the value of y is
# the default argument, or user-supplied?

foo(1, "bar") =user-supplied
foo(1) =default
Why are you trying to make this distinction? That is, why should passing
in "bar" be any different from getting the default value "bar"

You could do something like::
>>def foo(x='b a r'):
... if x is foo.func_defaul ts[0]:
... print 'default'
... else:
... print 'supplied'
...
>>foo('b a r')
supplied
>>foo()
default

But that won't really work if your default value gets interned by
Python, like small integers or identifier-like string literals::
>>def foo(x='bar'):
... if x is foo.func_defaul ts[0]:
... print 'default'
... else:
... print 'supplied'
...
>>bar = ''.join(chr(i) for i in [98, 97, 114])
foo(bar)
supplied
>>foo('bar')
default
STeVe
Feb 2 '07 #3
En Fri, 02 Feb 2007 15:30:53 -0300, Igor V. Rafienko <ig***@ifi.uio. no>
escribió:
>I was wondering whether it was possible to find out which parameter
value is being used: the default argument or the user-supplied one.
That is:

def foo(x, y="bar"):
# how to figure out whether the value of y is
# the default argument, or user-supplied?

foo(1, "bar") =user-supplied
foo(1) =default
You can use None as a flag:

def foo(x, y=None):
if y is None: y="bar"
...

If None is valid, use your own flag:

_marker=object( )
def foo(x, y=_marker):
if y is _marker: y="bar"
...

--
Gabriel Genellina

Feb 2 '07 #4
ig***@ifi.uio.n o (Igor V. Rafienko) writes:
I was wondering whether it was possible to find out which parameter
value is being used: the default argument or the user-supplied one.
That is:

def foo(x, y="bar"):
# how to figure out whether the value of y is
# the default argument, or user-supplied?
If it doesn't make a difference, use "bar".

If it *does* make a difference, use a unique object:

===== wombat.py =====
Y_DEFAULT = object()

def foo(x, y=Y_DEFAULT):
if y is Y_DEFAULT:
# no value for y was supplied
else:
# y value was specified by caller
=====

===== fnord.py =====

import wombat

foo("spam") # 'y' argument gets unique default object
foo("spam", "eggs") # 'y' argument is supplied by caller
=====

By using a unique object, and comparing on "is", you make it clear
that this is never going to match any other value that is created
elsewhere in the program.

Of course, the "consenting adults" maxim applies: if a perverse user
wnats to call 'foo("spam", wombat.Y_DEFAUL T)' this doesn't prevent it,
but then they've explicitly asked for it.

--
\ "A lot of people are afraid of heights. Not me, I'm afraid of |
`\ widths." -- Steven Wright |
_o__) |
Ben Finney

Feb 3 '07 #5
On Feb 2, 1:30 pm, i...@ifi.uio.no (Igor V. Rafienko) wrote:
Hi,

I was wondering whether it was possible to find out which parameter
value is being used: the default argument or the user-supplied one.
That is:

def foo(x, y="bar"):
# how to figure out whether the value of y is
# the default argument, or user-supplied?

foo(1, "bar") =user-supplied
foo(1) =default

{}.pop seems to be able to make this dictinction.

I've checked the inspect module, but nothing obvious jumped at me. Any
hints?
I don't know why you might want to distinguish between the two in
practice (the unique object idea mentioned in other posts should
handle most uses cases), but if you insist, here's one way to do it:

import inspect

def determine_suppl ied_args(func):
varnames,_,_,de faults = inspect.getargs pec(func)
num_varnames = len(varnames); num_defaults = len(defaults)
def wrapper(*args, **kwds):
max_defaults = min(num_default s, num_varnames-len(args))
supplied_args = dict(zip(varnam es,args))
default_args = {}
if max_defaults 0:
for var,default in zip(varnames[-max_defaults:], defaults[-
max_defaults:]):
# if passed as keyword argument, don't use the default
if var in kwds:
supplied_args[var] = kwds[var]
else:
default_args[var] = default
wrapper._suppli ed_args = supplied_args
wrapper._defaul t_args = default_args
return func(*args, **kwds)
return wrapper
@determine_supp lied_args
def f(x, y='bar', z=None, *args, **kwds):
print "Supplied:" , f._supplied_arg s
print "Default:", f._default_args

>>f(1)
Supplied: {'x': 1}
Default: {'y': 'bar', 'z': None}
>>f(1, 'bar')
Supplied: {'y': 'bar', 'x': 1}
Default: {'z': None}
>>f(1, y='bar')
Supplied: {'y': 'bar', 'x': 1}
Default: {'z': None}
>>f(1, z=None)
Supplied: {'x': 1, 'z': None}
Default: {'y': 'bar'}
>>f(1, 'bar', None)
Supplied: {'y': 'bar', 'x': 1, 'z': None}
Default: {}
>>f(1, 'bar', z=None)
Supplied: {'y': 'bar', 'x': 1, 'z': None}
Default: {}
>>f(1, z=None, y='bar')
Supplied: {'y': 'bar', 'x': 1, 'z': None}
Default: {}
Regards,
George

Feb 3 '07 #6
[ George Sakkis ]

First of all, thanks to everyone who replied.

[ ... ]
I don't know why you might want to distinguish between the two in
practice (the unique object idea mentioned in other posts should
handle most uses cases), but if you insist, here's one way to do it:

There is no actual code situation where it happens. I was simply
intrigued by the problem and could not find an answer.

Since {}.pop behaves this way, I checked the C code. Apparently, it
*is* quite easy from C, since PyArg_UnpackTup le and clever initial
values (NULL vs. Py_None) make all the difference.

The inspect-suggestion is, unfortunately, a bit more difficult to
comprehend than I initially hoped for :)

Thanks for all the suggestions

[ ... ]

ivr
--
"...but it's HDTV -- it's got a better resolution than the real world."
-- Fry, "When aliens attack"
Feb 6 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
4621
by: Roy Smith | last post by:
I've got a function that takes a couple of optional keyword arguments. I want to check to make sure I didn't get passed an argument I didn't expect. Right now I'm doing: conversion = None drop = False for key, value in kwArgs.items(): if key == 'conversion': conversion = value elif key == 'drop':
46
3535
by: J.R. | last post by:
Hi folks, The python can only support passing value in function call (right?), I'm wondering how to effectively pass a large parameter, such as a large list or dictionary? It could achieved by pointer in C++, is there such way in Python? Thansk in advance. J.R.
14
5280
by: Edward Diener | last post by:
In the tutorial on functions there are sections on default arguments and keyword arguments, yet I don't see the syntactic difference between them. For default arguments the tutorial shows: def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while for keyword arguments the tutorial shows: def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
9
2665
by: Bart Nessux | last post by:
Are these equivelent? Is one approach prefered over the other #check to see if var contains something... if so proceed. if var is not None: continue #check to see if var is empty... if so prompt user again.
30
2261
by: Michael B Allen | last post by:
I have a general purpose library that has a lot of checks for bad input parameters like: void * linkedlist_get(struct linkedlist *l, unsigned int idx) { if (l == NULL) { errno = EINVAL; return NULL; }
8
1881
by: Brendan | last post by:
There must be an easy way to do this: For classes that contain very simple data tables, I like to do something like this: class Things(Object): def __init__(self, x, y, z): #assert that x, y, and z have the same length But I can't figure out a _simple_ way to check the arguments have the
10
2004
by: Fredrik Tolf | last post by:
If I have a variable which points to a function, can I check if certain argument list matches what the function wants before or when calling it? Currently, I'm trying to catch a TypeError when calling the function (since that is what is raised when trying to call it with an illegal list), but that has the rather undesirable side effect of also catching any TypeErrors raised inside the function. Is there a way to avoid that? Fredrik Tolf
4
2394
by: Patient Guy | last post by:
Does anyone have any coding rules they follow when doing argument checking? When arguments fail during check, do you return from the call with an ambiguous return value, or do you throw exceptions?
125
6629
by: jacob navia | last post by:
We hear very often in this discussion group that bounds checking, or safety tests are too expensive to be used in C. Several researchers of UCSD have published an interesting paper about this problem. http://www.jilp.org/vol9/v9paper10.pdf Specifically, they measured the overhead of a bounds
0
9719
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9597
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10620
Oralloy
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...
0
10369
jinu1996
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...
1
10372
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,...
1
7650
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6877
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();...
0
5682
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3008
bsmnconsultancy
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.