Need to pass Object by value into a list

A

Aaron

I have a data sructure setup and I populate it in a loop like so:

y=0
while X:
DS.name = "ASDF"
DS.ID = 1234

list[y] = DS;
y = y + 1

print list

This does not work because DS is passed in by reference causing all
entries into the list to change to the most current value. I cannot
find a "new" function in Python like there is in C++. How do you do
this in Python?
 
F

Fredrik Lundh

Aaron said:
I have a data sructure setup and I populate it in a loop like so:

y=0
while X:
DS.name = "ASDF"
DS.ID = 1234

list[y] = DS;
y = y + 1

print list

This does not work because DS is passed in by reference causing all
entries into the list to change to the most current value. I cannot
find a "new" function in Python like there is in C++. How do you do
this in Python?

I assume DS is a class?

to create an instance of a class, call the class object:

L = []

while X:
ds = DS()
ds.name = "ASDF"
ds.id = 1234
L.append(ds)

spending some time with the tutorial might help:

http://docs.python.org/tut/tut.html

(lists are described in chapter 3, classes in chapter 9)

</F>
 
B

Bruno Desthuilliers

Aaron a écrit :
I have a data sructure setup and I populate it in a loop like so:

y=0
while X:
DS.name = "ASDF"
DS.ID = 1234
list[y] = DS;
y = y + 1

print list

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/tmp/python-9150sSF", line 2, in ?
while X:
NameError: name 'X' is not defined

Please post running code. The rule is:
- explain what you did
- explain what you expected
- explain what you've got
- post the minimal running code that reproduce the problem

Here are a short listing of errors and bad style in this code:

1/ DS is not defined
2/ X is not defined
3/ 'list' is the name of the builtin class list. The list *class* is
unsubscriptable.
4/ Assuming you rebound the name 'list' to a list instance (which is a
very Bad Thing(tm)), you still can't assign to an inexistant index
5/ even if DS and X were defined, this loop would run forever
6/ In Python, identifiers in uppercase are constants (well... this is
only a convention, but convention in Python are part of the language,
even if there's nothing to enforce them)
7/ you mix arbitrary naming conventions ('DS.name' vs 'DS.ID', 'X' vs 'y').

Either this is not your real code or you did not try to run this code.
In fact, I guess this is not your real code AND you did not try to run
it. Please do *yourself* a favor: post running code (I don't mean 'code
that don't crash', I mean: 'code that reproduce your real problem').
This does not work

"Does not work" is the worst possible description of a problem.

Now effectively, this code (the one you posted, not the one you are
describing) crashes for a very obvious reason (see point n°1 above). The
code you are describing (which is obviously different...) "works" - it
may not behave how you'd expect it to, but this is another problem.
because DS is passed in by reference causing all
entries into the list to change to the most current value.

DS is not 'passed by reference', since there is no function call in your
code. A reference to the object bound to the name DS is stored (well, I
assume this is what happen in your real code) in the list - which is
not the same thing.

<digression>
BTW, you need to understand that, in Python, an identifier is just a
name bound to a reference to an object. Think of the namespace as a
hashtable with names as keys and references to objects as values (this
exactly how it's implemented). When it comes to function calls, the
*name* is local to the function, but the object referenced by the name
is the original object. If you rebind the name (ie: 'assign' another
object to it), this change will be local, because the *name* is local.
But if you modify the object itself, this will impact the 'original'
object, ie:

def fun(aList, anotherList):
# rebind local name 'aList', original object not impacted
aList = [1, 2, 3]

# modify ('mutate') object bound to 'anotherList',
# original object impacted
anotherList.append(42)

listOne = [4, 5, 6]
listTwo = [7, 8, 9]

fun(listOne, listTow)
print listOne
print listTwo
I cannot
find a "new" function in Python like there is in C++.

<pedantic>
In C++, 'new' is an operator, not a function.
</pedantic>

In Python, classes are callable objects (a callable is something like a
function - or, should I say, a function is a kind of callable object -
everything in Python being an object...) that return an instance when
called. So there is no need for a 'new' operator - just call the class
object (like you'd call a function), and you'll get an instance. Also,
if the class has an '__init__' method, this method will be called after
object instanciation, with the arguments passed when calling the class.

ie:

class Foo(object):
def __init__(self, name):
self.name = name

f = Foo('foo')
f.name
=> 'foo'
How do you do
this in Python?

class Ds(object):
def __init__(self, id, name):
self.id = id
self.name = name

x = 42 # or any other integer value

# short way
ds_list = [Ds(1234, "ASDF") for i in range(x)]
print ds_list

# verbose way:
ds=list = []
for i in range(x):
ds_list.append(Ds(1234, "ASDF")

print ds_list
ds_list[0].name="FOO"
print ds_list

HTH
 

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
474,264
Messages
2,571,323
Members
48,006
Latest member
TerranceCo

Latest Threads

Top