Python feature Functools gains a new decorator. `Defaults' allows its caller to placehold non-None defaults; it becomes unnecessary to know the value a place defaults to. It might be useful in cases where you want the calling signature to look alike for a group of dispatched functions and the added overhead the decorator adds isn't a problem. But you probably wouldn't want that overhead all the time, so having it as an optional decorator would be good. -Ron Adam A survey of the standard library for Python v2.5, produced via a script [7], gave the following statistics for the standard library (608 files, test suites were excluded): total number of non-None immutable default arguments: 1585 (41.5%) total number of mutable default arguments: 186 (4.9%) total number of default arguments with a value of None: 1813 (47.4%) total number of default arguments with unknown mutability: 238 (6.2%) total number of comparisons to None: 940 So, I'd say that they're pretty frequent, with at least 41.5% of all std lib default values being non-None. -Chris Rebert `Defaults' may be used as well when "None actually is a valid and meaningful value," as Jim Jewett says. He goes on to say, When None appears in a parameter list (or an argument list, at the calling site), it might really be a sentinel for something else, and that is a wart. Rationale: `None' serves double-duty. Use `Defaults' to off-load responsibility. Usage: defaults( wrapped ) >>> @defaults >>> def f(a=123, b=None, c='abc'): >>> return a, b, c >>> >>> DfV = defaults.absent >>> f(123, DfV, 'abc') 123, None, 'abc' >>> f(123, ObjA, DfV) 123, , '' -Adam Roughly equivalent to: absent= object() #A signal object. def defaults( callable ): def newfunc( *args,**kwargs ): args= list(args) for i,j in enumerate( args ): if j is absent: offset= \ callable.func_code.co_argcount -\ len(callable.func_defaults) args[i]= callable.func_defaults[i-offset] return callable( *args,**kwargs ) newfunc.callable= callable return newfunc Test suite shown here: #from functools import defaults,absent from default import defaults,absent import unittest class DefaultTest(unittest.TestCase): @staticmethod @defaults def f( a,b=None,c='abc' ): print a,b,c return a,b,c def test1( self ): self.assertEqual( self.f( 0,absent,'def' ), ( 0,None,'def') ) self.assertEqual( self.f( 0,'athing',absent ), ( 0,'athing','abc' ) ) self.assertEqual( self.f( 0,c='ghi' ), ( 0,None,'ghi' ) ) self.assertEqual( self.f( 0,absent ), ( 0,None,'abc' ) ) self.assertEqual( self.f( 0,c=absent ), ( 0,None,absent ) ) self.assertEqual( self.f( *(0,'b') ), ( 0,'b','abc' ) ) self.assertEqual( self.f( c=2, *(0,'b') ), ( 0,'b',2 ) ) self.assertRaises( TypeError, self.f, b=2, *(0,'b') ) self.assertEqual( self.f( c=2, *(0,absent) ), ( 0,None,2 ) ) if __name__== '__main__': unittest.main()