[Tutor] Python Function Doubt

spir denis.spir at free.fr
Tue May 26 19:21:51 CEST 2009


Le Tue, 26 May 2009 19:42:34 +0530,
nikhil <nik.mis at gmail.com> s'exprima ainsi:

> Hi,
> 
> Thanks for reply.
> 
> I went through the link you provided. It was very helpful.
> 
> What I understood is this,
> 
> --> Objects are created for default argument types, inside the function
> object.

... for default arguments -- not types. Inside the function object, yes:

=====================
def exp(n, power=2, fool=[1,2,3]):
	return n ** power

print dir(exp)	# attributes of function exp
print exp.func_defaults
==>
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

(2, [1, 2, 3])
=====================

Note: I think args called "func_*" are renamed "*" alone in later versions of python.

> This
>      happens only once when the function definition statement is executed.
> These objects
>      persist between function calls and not destroyed/garbage collected.
> 
> --> Since List is a mutable object, changes are made to the same object and
> hence
>      it is visible between function calls.
> 
> Is my understanding correct ?

Yes; this is true especially when the said list is changed from inside the func body. 
This is sometimes consciously used to make an argument act like a so-called "static" variable (which despite the name is a dynamic, changeable value). For instance:

def numberSum(n, numbers=[]):
	numbers.append(n)
	print "Sum so far: %s" % sum(numbers)

But the list of numbers is, in fact, an attribute of the function considered as an object, so that this may be more clearly written:

def numberSum(n):
	numberSum.numbers.append(n)
	print "Sum so far: %s" % sum(numberSum.numbers)
numberSum.numbers = []

It may happen too that the default argument is specified from outside, can change at runtime... even intentionally. For instance, a default value can depend on configuration a user may change at runtime.
To make this explicite and obvious, it may be better to write things like:

def func(arg, defaultarg=None):
	# if not provided, get defaultarg from current user config
	if defaultarg is None:
		defaultarg = defaultFromConfig()
	.......


> If so, I have a small doubt regarding function arguments.
> 
> Are objects for arguments, that persist between function calls, created
> during function definition ONLY when they have default values ?

Yes. The issue is that the local variables (like "numbers" above, in the func body) that receive these default objects at call time get them, like always in python, by reference. So that when the object happens to be mutable, any change is shared by the local variable and the default value.

> OR
> 
> Objects are created for arguments irrespective of whether it has a default
> value or not, but they are not persistent ( i.e a new object is created for
> every function call ) ?

Here I don't really understand: how can python create an object that has no value?
At *call time*, python will define *all* local variables that match an argument. The ones that are not provided and have a default will point to the default objects. For the other ones, python will create short-life objects.
You may pay attention to the distinction between a name, an object and the binding of both (~ variable).

> Regards,
> Nikhil


------
la vita e estrany


More information about the Tutor mailing list