Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > newbie questions

Reply
Thread Tools

newbie questions

 
 
houbahop
Guest
Posts: n/a
 
      12-11-2004
Hello everyone,
I'm new to python dev, and there are some things I don't understand
about arrays and subs

In my code, I have an array of strings (in the main function)

self.SortiesAnimeTitreLabel = []

then I pass this array to a sub that fill it it ( using.append('blabla') :

self.InstancierLabelsTitre(self.SortiesAnimeTitreL abel)

then, I need to reset this var, and this is my problem, I have created an
other sub to reset and it doesn't seems to work, like if the parameter was
pass by value instead of by reference. here is the sub :


def RAZVarAnimesDuJour(self,oSortiesAnimeTitreLabel):
for i in xrange(len(oSortiesAnimeTitreLabel)):
del oSortiesAnimeTitreLabel[i]

it doesn't emty my var (i don't want to destroy the var, just make it like
if it just have been created

do yo have any idea of what is causing this problem?
is it possible to do self.SortiesAnimeTitreLabel = [] to reset the var? (it
seems to work outside of the sub, but I believe that the var I'm erasing is
not the one I want but a local copy.


Thank you for your help.
Dominique.


 
Reply With Quote
 
 
 
 
Erik Johnson
Guest
Posts: n/a
 
      12-11-2004
> do yo have any idea of what is causing this problem?
> is it possible to do self.SortiesAnimeTitreLabel = [] to reset the var?

(it
> seems to work outside of the sub, but I believe that the var I'm erasing

is
> not the one I want but a local copy.



Yeah. I'm no Python guru, but I have a pretty good idea. Your intuition
is correct - you're killing a local copy. Functions (and methods) have their
own namespace. Variables declared within a function are local that that
function's name space, as well as formal variables that appear on the
function declartion (definition) line.

>>> z = 'z'
>>> def f(x):

.... print dir()
.... del x
.... print dir()
....
>>> z

'z'
>>> f(z)

['x']
[]
>>> z

'z'
>>>


Secondly, within a class method, x and self.x are two different things.
The first is just a variable within the method namespace, the second is an
object attribute. So, for your example, there probably is no reason to go
kill each list element individually (unless perhaps other code is accessing
that list NOT through the object.) Within an object method, if you honestly
don't want to kill the variable, you could just say:

self.SortiesAnimeTitreLabel = []

and that replaces that object's list with an empty one. Unless there are
other references to that same list, hte garbage collector will take it.
Other code accessing the list through this object's handle will see the new,
empty list, which I think is what you want in this case.

HTH,
-ej


 
Reply With Quote
 
 
 
 
Adam DePrince
Guest
Posts: n/a
 
      12-11-2004
On Fri, 2004-12-10 at 22:17, Erik Johnson wrote:
> > do yo have any idea of what is causing this problem?
> > is it possible to do self.SortiesAnimeTitreLabel = [] to reset the var?

> (it
> > seems to work outside of the sub, but I believe that the var I'm erasing

> is
> > not the one I want but a local copy.

>
>
> Yeah. I'm no Python guru, but I have a pretty good idea. Your intuition
> is correct - you're killing a local copy. Functions (and methods) have their
> own namespace. Variables declared within a function are local that that
> function's name space, as well as formal variables that appear on the
> function declartion (definition) line.
>
> >>> z = 'z'
> >>> def f(x):

> ... print dir()
> ... del x
> ... print dir()
> ...
> >>> z

> 'z'
> >>> f(z)

> ['x']
> []
> >>> z

> 'z'
> >>>

>
> Secondly, within a class method, x and self.x are two different things.
> The first is just a variable within the method namespace, the second is an
> object attribute. So, for your example, there probably is no reason to go
> kill each list element individually (unless perhaps other code is accessing
> that list NOT through the object.) Within an object method, if you honestly
> don't want to kill the variable, you could just say:
>
> self.SortiesAnimeTitreLabel = []
>
> and that replaces that object's list with an empty one. Unless there are
> other references to that same list, hte garbage collector will take it.
> Other code accessing the list through this object's handle will see the new,
> empty list, which I think is what you want in this case.
>
> HTH,
> -ej


At risk of encouraging a "newbie" from partaking in the hideous and vile
vice of "programming by side effect" there is a way to make python do
almost what you want.

First, lets look at the "is" operator. is is like ==, but instead of
answering the question "are these objects equivalent," it asks "are they
actually the same object."

>>> a = []
>>> b = []
>>> a is b # They are different objects

False
>>> a == b # They have the sample value

True
>>> b = a # Now we are assigning to b the same object as a.

# There are two references to it.
>>> a is b

True

Alright. Now, as Erik pointed out if you assign to the variable the
computer will add that to the local name space. This happens at
"compile" time (which is right after you hit enter twice at the CPython
command line.)

For an example of this:

>>> a = 0
>>> def b():

.... print a
....
>>> def c():

.... print a
.... a = 1
....
>>> b()

0
>>> c()

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in c
UnboundLocalError: local variable 'a' referenced before assignment

In b(), a was taken as being from the line above. In c, it was from the
local name space.

So, how do we affect what you want? Now promise me that you will never,
ever do this in code you consider yourself proud of. Realize I'm
sharing this in the same spirit that kids in a drivers ed class might
view gory accident pictures.

Fortunately for you, lists are mutable. Assigning to a auto-magically
makes it part of your local name space, hiding the global a. But, if
you don't assign to a, you can still access it. And because you can
access it you can mutate it.

>>> a = [1]
>>> def b():

.... a.append( 2 )
....
>>> def c():

.... a[0] = 0 # Yes, an assignment, but not to a
....
>>> def d():

.... a[:] = []
....
>>> b()
>>> a

[1, 2]
>>> c()
>>> a

[0, 2]
>>> d()
>>> a

[]
>>>


Now forgive me ... what you really want to do is follow Erik's advice.




Adam DePrince


 
Reply With Quote
 
Mike Meyer
Guest
Posts: n/a
 
      12-11-2004
Adam DePrince <(E-Mail Removed)> writes:

> Alright. Now, as Erik pointed out if you assign to the variable the
> computer will add that to the local name space. This happens at
> "compile" time (which is right after you hit enter twice at the CPython
> command line.)
>
> For an example of this:
>
>>>> a = 0
>>>> def b():

> ... print a
> ...
>>>> def c():

> ... print a
> ... a = 1
> ...
>>>> b()

> 0
>>>> c()

> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "<stdin>", line 2, in c
> UnboundLocalError: local variable 'a' referenced before assignment
>
> In b(), a was taken as being from the line above. In c, it was from the
> local name space.
>
> So, how do we affect what you want?


I *have* to point out here that you can write c as:

>>> a = 2
>>> def c():

.... global a
.... print a
.... a = 1
....
>>> c()

2
>>>


The one (and so far only) place you can declare a variable in Python.

<mike
--
Mike Meyer <(E-Mail Removed)> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
 
Reply With Quote
 
Roel Schroeven
Guest
Posts: n/a
 
      12-11-2004
houbahop wrote:
> def RAZVarAnimesDuJour(self,oSortiesAnimeTitreLabel):
> for i in xrange(len(oSortiesAnimeTitreLabel)):
> del oSortiesAnimeTitreLabel[i]
>
> it doesn't emty my var (i don't want to destroy the var, just make it like
> if it just have been created


Other posts are missing the point somewhat, I think. While they do
recommend better ways of doing what you want to do, they don't say why
your function doesn't work.

What exactly happens when you execute your code? When I try it, I get an
exception:

>>> alist = range(5)
>>> def a(alist):

for i in xrange(len(alist)):
del alist[i]


>>> a(alist)


Traceback (most recent call last):
File "<pyshell#22>", line 1, in -toplevel-
a(alist)
File "<pyshell#21>", line 3, in a
del alist[i]
IndexError: list assignment index out of range


What happens is this: the first time, the first element is deleted. This
causes all other elements to shift: the second element becomes the first
one, the third becomes the second, and so on. Or:

0, 1, 2, 3, 4
becomes
1, 2, 3, 4

The list gets shorter each time. But you're still looping over the whole
length of the list, which means after some time you're accessing
elements that no longer exist.

One way to solve it is to loop backwards: first delete the last element,
than the next to last, etc.


Apart from that, it's much easier and clearer to reset the list with just

alist = []

--
"Codito ergo sum"
Roel Schroeven
 
Reply With Quote
 
houbahop
Guest
Posts: n/a
 
      12-11-2004
Thank you everyone, but I still not understand why such a comon feature like
passing parameters byref that is present in most serious programming
languages is not possible in a clean way,here in python.

I have the habit to never use globals as far as possible and this involve
that my main function is passing some parameters by reference to subs to
allow them to modify the vars.

I would be sad to break my structured programming scheme because a lack of
feature.

In others languages you can use things like pointers to strings or
Mysub(byref MyVar) ....

and it does the trick


 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      12-11-2004
houbahop wrote:
> Thank you everyone, but I still not understand why such a comon feature like
> passing parameters byref that is present in most serious programming
> languages is not possible in a clean way,here in python.


I understand from this statement that Java is not a serious programming
language?

> I have the habit to never use globals as far as possible and this involve
> that my main function is passing some parameters by reference to subs to
> allow them to modify the vars.


I don't see why lack of pass-by-reference would force you to use globals...

>>> class C(object):

.... def __init__(self):
.... self.list = []
.... def fill(self, iterable):
.... self.list.extend(iterable)
.... def empty(self):
.... self.list = []
....
>>> c = C()
>>> c.list

[]
>>> c.fill(pow(x, 3, 29) for x in range(10))
>>> c.list

[0, 1, 8, 27, 6, 9, 13, 24, 19, 4]
>>> c.empty()
>>> c.list

[]

Or by globals do you mean instance variables? If you don't want any
instance variables (which means you don't really want OO), you can still
clear your list as long as you have any name bound to the list object:

>>> def clear(lst):

.... while lst:
.... lst.pop()
....
>>> x = [pow(x, 7, 19) for x in range(10)]
>>> x

[0, 1, 14, 2, 6, 16, 9, 7, 8, 4]
>>> clear(x)
>>> x

[]

or alternatively:

>>> def clear(lst):

.... lst[:] = []
....
>>> x = [pow(x, 7, 19) for x in range(10)]
>>> x

[0, 1, 14, 2, 6, 16, 9, 7, 8, 4]
>>> clear(x)
>>> x

[]

Note that neither of these functions requires pass-by-reference; the lst
local in the function is not the same name as the x local outside the
function. But since you're basically just passing a "pointer" by value,
both "variables" still "point" to the same object (or in Python terms,
both "names" are "bound" to the same object). To apply an affect that
is visible to all names bound to an object, you simply need to mutate
the object. In the cases above, this is just a matter of using the
appropriate object method (list.pop or list.__setslice__ respectively
above).

Is this so bad?

Steve
 
Reply With Quote
 
Mel Wilson
Guest
Posts: n/a
 
      12-11-2004
In article <pXBud.87963$(E-Mail Removed)>,
"houbahop" <d.lapasset[Remove me)@chello.fr> wrote:
>Thank you everyone, but I still not understand why such a comon feature like
>passing parameters byref that is present in most serious programming
>languages is not possible in a clean way,here in python.
>
>I have the habit to never use globals as far as possible and this involve
>that my main function is passing some parameters by reference to subs to
>allow them to modify the vars.
>
>I would be sad to break my structured programming scheme because a lack of
>feature.
>
>In others languages you can use things like pointers to strings or
>Mysub(byref MyVar) ....
>
>and it does the trick


It isn't a problem with passing by reference. The
passing-by-reference part works just fine. Putting in a
print statement to trace what's actually happening:


Python 2.3 (#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3,4,5]
>>> def X(s):

.... for i in xrange (len (s)):
.... del s[i]
.... print 'X:', s
....
>>> X(a)

X: [2, 3, 4, 5]
X: [2, 4, 5]
X: [2, 4]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in X
IndexError: list assignment index out of range
>>> a

[2, 4]
>>>



As the last line shows, lots of things got removed from
`a` .. but not everything. Roel Schroeven explained why.

Regards. Mel.
 
Reply With Quote
 
houbahop
Guest
Posts: n/a
 
      12-11-2004
Hi,

"Steven Bethard" <(E-Mail Removed)> a écrit dans le message de news:
bvCud.743222$8_6.73414@attbi_s04...
> houbahop wrote:
>> Thank you everyone, but I still not understand why such a comon feature
>> like passing parameters byref that is present in most serious programming
>> languages is not possible in a clean way,here in python.

>
> I understand from this statement that Java is not a serious programming
> language?


I didn't want to say that.
In fact, python is the first language I use that is like java 100% oriented
object.
I didn't realise that the main function, was an object too ! (and I don't
really knew that self.something was meaning that it was a class attribute..
just grabed this in a code found on the net )
My habit in VB was to start a new project with a module (that is not an
object and doesn't have class functions) and then calling object functions
and passing them local to the main objects.

like this :

class a()
blabla
class b()
blabla

main()
create a instance
create b instance
b()
a(b)
end main

But in the very small script that I'm coding, I don't really need OOP and I
will not use it even if I really like that.



> I don't see why lack of pass-by-reference would force you to use
> globals...
> Or by globals do you mean instance variables? If you don't want any
> instance variables (which means you don't really want OO), you can still
> clear your list as long as you have any name bound to the list object:


You're right.

> >>> def clear(lst):

> ... while lst:
> ... lst.pop()
> ...
> >>> x = [pow(x, 7, 19) for x in range(10)]
> >>> x

> [0, 1, 14, 2, 6, 16, 9, 7, 8, 4]
> >>> clear(x)
> >>> x

> []
>
> or alternatively:
>
> >>> def clear(lst):

> ... lst[:] = []
> ...
> >>> x = [pow(x, 7, 19) for x in range(10)]
> >>> x

> [0, 1, 14, 2, 6, 16, 9, 7, 8, 4]
> >>> clear(x)
> >>> x

> []
>
> Note that neither of these functions requires pass-by-reference; the lst
> local in the function is not the same name as the x local outside the
> function. But since you're basically just passing a "pointer" by value,
> both "variables" still "point" to the same object


Passing a pointer by value appears to me as passing a var by reference.

(or in Python terms,
> both "names" are "bound" to the same object). To apply an affect that is
> visible to all names bound to an object, you simply need to mutate the
> object. In the cases above, this is just a matter of using the
> appropriate object method (list.pop or list.__setslice__ respectively
> above).


Thanks I will try all of that, but what does really means mutating in
python? It's the first time I hear this word in programming )
Dominique


 
Reply With Quote
 
Diez B. Roggisch
Guest
Posts: n/a
 
      12-11-2004
> Thanks I will try all of that, but what does really means mutating in
> python? It's the first time I hear this word in programming )


An object is called mutable if you can alter it - immutable otherwise. In
java and python e.g. strings are immutable. In python, tuples are
immutable:

>>> a = (1,2)
>>> a[0] = 3

TypeError: object doesn't support item assignment

but lists are mutable:

>>> a = [1,2]
>>> a[0] = 3
>>> a

[3,2]

But objects in tuples can be mutable:

>>> a = (1, [2,3])
>>> a[1].append(4)
>>> a

(1,[2,3,4])

Numbers are also immutable. 1 is 1 always.


The most important thing to know about python and variables is that
variables are only names pointing/referring to values. You might be able to
modify the values if they are mutable, but assigning a value to a variable
means that you simply rebind its name to a new value - not that you alter
it. Consider this:

>>> a = 1
>>> b = a
>>> a = 2
>>> print a, b

2 1



--
Regards,

Diez B. Roggisch
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
newbie with newbie questions JohnE ASP .Net 3 08-17-2009 10:10 PM
Malloc and free questions - learner questions pkirk25 C Programming 50 10-04-2006 02:22 PM
Questions on Canon 300D and etc. questions regarding digital photography Progressiveabsolution Digital Photography 12 03-24-2005 05:18 PM
Newbie questions - Couple of VC++ questions regarding dlls and VB6 Ali Syed C Programming 3 10-13-2004 10:15 PM
Re: Questions....questions....questions Patrick Michael A+ Certification 0 06-16-2004 04:53 PM



Advertisments