variable & scoping question.

C

Cornelius Keller

Hi,

I'm a quite fresh python programmer, (6 Month python experience).
Today I found something I absolotly don'nt understand:

given the following function:

def test_effect(class_id=None,class_ids=[]):
if class_id is not None:
if class_id not in class_ids:
class_ids.append(int(class_id))

print class_ids

I observe that the class_ids array is growing when it is called with
different class id's.

I expected class_ids to be [] if the keyword argument is not set, but
it seems to beahve like a static variable if not set.

example:


In [3]: test.test_effect(class_id=1)
[1]

In [4]: test.test_effect(class_id=1)
[1]

In [5]: test.test_effect(class_id=2)
[1, 2]

In [6]: test.test_effect(class_id=2)
[1, 2]

In [7]: test.test_effect(class_id=3)
[1, 2, 3]

Is this an intended python beahviour?

sincerly
- Cornelius
 
D

Diez B. Roggisch

Cornelius said:
Hi,

I'm a quite fresh python programmer, (6 Month python experience).
Today I found something I absolotly don'nt understand:

given the following function:

def test_effect(class_id=None,class_ids=[]):
    if class_id is not None:
        if class_id not in class_ids:
            class_ids.append(int(class_id))

    print class_ids

I observe that the class_ids array is growing when it is called with
different class id's.

I expected class_ids to be [] if the keyword argument is not set, but
it seems to beahve like a static variable if not set.

http://effbot.org/zone/default-values.htm

Diez
 
F

Francesco Bochicchio

Cornelius said:
I'm a quite fresh python programmer, (6 Month python experience).
Today I found something I absolotly don'nt understand:
given the following function:
def test_effect(class_id=None,class_ids=[]):
    if class_id is not None:
        if class_id not in class_ids:
            class_ids.append(int(class_id))
    print class_ids
I observe that the class_ids array is growing when it is called with
different class id's.
I expected class_ids to be [] if the keyword argument is not set, but
it seems to beahve like a static variable if not set.

http://effbot.org/zone/default-values.htm

Diez

Maybe on the first page of python.org there should be a 'python
gotchas' link to a page listing these few
non-intuituive peculiarities of our beloved snake ... same goes for
the official python tutorial ...

Ciao
 
M

MRAB

Francesco said:
Cornelius said:
Hi,
I'm a quite fresh python programmer, (6 Month python experience).
Today I found something I absolotly don'nt understand:
given the following function:
def test_effect(class_id=None,class_ids=[]):
if class_id is not None:
if class_id not in class_ids:
class_ids.append(int(class_id))
print class_ids
I observe that the class_ids array is growing when it is called with
different class id's.
I expected class_ids to be [] if the keyword argument is not set, but
it seems to beahve like a static variable if not set.
http://effbot.org/zone/default-values.htm

Diez

Maybe on the first page of python.org there should be a 'python
gotchas' link to a page listing these few
non-intuituive peculiarities of our beloved snake ... same goes for
the official python tutorial ...
Should they be called 'snake bites'? Well, pythons are constrictors, not
biters, but if Python is being non-intuitive... :)
 
E

Ethan Furman

Cornelius Keller wrote:
[snip]
I still think this is very confusing, because default values don't
behave like most people would expect without reading the docs.

- Cornelius

Why would you expect to become a good programmer of _any_ language
without reading its docs?

~Ethan~
 
D

Dennis Lee Bieber

Ok thank you.
I' understand now why.
I still think this is very confusing, because default values don't
behave like most people would expect without reading the docs.
They work as any Python object would... Given a single point of
definition everything else is up to whether it is a mutable object or
not...

alist = [] #mutable
avalue = 3.14159 #immutable

def thing1():
alist.append(2) #mutates outer scope
avalue = 2 #local

def thing2():
global avalue
alist = [ avalue ] #binding is to local
avalue = 2 #rebinds outer scope

def credenza(av, al):
al.append(av) #mutates al
av = 3 #acts as local

credenza(avalue, alist)



Default arguments are just an assignment statement to the object
created during the parse/compile phase.
 
J

J. Cliff Dyer


Ok thank you.
I' understand now why.
I still think this is very confusing, because default values don't
behave like most people would expect without reading the docs.

- Cornelius

You are correct. This is confusing at first blush. The important thing
to remember is: *don't do that.* Learn the pythonic workaround of using
None in your parameters whenever you want a default empty list, and
don't let it bother you too much. Overall, python is a remarkably well
designed language. This is one of the relatively rare warts that crept
in because it enables a broader cleanliness of design.

Cheers,
Cliff
 
S

Steven D'Aprano


Ok thank you.
I' understand now why.
I still think this is very confusing, because default values don't
behave like most people would expect without reading the docs.


Really? How do you expect the default value to behave in this example?
.... print x
....1249972984.33

You get the same default object each time you call the function, NOT a
fresh one created. I'm sure I'd be terribly confused if Python re-
evaluated the default value each time I called the function.

There's no difference between this and the case x=[], except that lists
are mutable and floats aren't. You get the same default list each time,
it just has different stuff in it. The alternative would be to get a
different list each time, and that would require re-evaluating the
default each time the function was called, which is horrible.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top