Add lists to class?

B

BBands

I have a list with some strings in in it, 'one', 'two' 'three' and so
on. I would like to add lists to a class with those names. I have no
way of knowing what will be in the list or how long the list will be in
advance.

Something like:

class master:
def __init__(self, list):
self.count = len(list)
for line in list:
self.line = [] # obviously this doesn't work

list = ['one', 'two', 'three']

a = master(list)

so that I get:

dir(a)

['_doc__', '_init__', '_module__', 'one', 'two', 'three']

instead of:

dir(a)

['_doc__', '_init__', '_module__', 'line']


TIA,

jab
 
L

Larry Bates

I think what you want is this (not tested):

class master:
def __init__(self, list):
self.count = len(list)
for entry in list:
self.__dict__[entry]= []


This will get you master class with three attributes

a = master(list)

a.one
a.two
a.three

each containing an empty list. You can then do things
like:

a.one.append(something)
a.three.append(something)

Larry Bates
 
B

BBands

tested and working...

jab, now possessing an embarrassment of riches, says "Thanks!"
 
M

Mike Meyer

BBands said:
I have a list with some strings in in it, 'one', 'two' 'three' and so
on. I would like to add lists to a class with those names. I have no
way of knowing what will be in the list or how long the list will be in
advance.

Others have told you how to do it. Now I'm going to tell you why you
shouldn't.

First, since you don't know the names of the attributes you added, you
can't possibly write code that references them in the normal way. So
is there really much point in making them an attribute at all?

Second, since you don't know the names of the attributes you added,
you don't know if one of more of them is going to clobber a feafure of
the class that you want to use for something else. I.e., consider:
.... pass
.... Traceback (most recent call last):

I.e. - if someone adds a __str__ attribute to your class, you won't be
able to print it any more. Not a good thing.

In general, you probably want a dictionary instead of attributes:
.... def __init__(self, l):
.... for i in l:
.... self = []
....
c = C(['a', 'b', 'c'])
c['a'] []

You didn't say why you wanted to do this; maybe you really do have a
good reason. But that would be an exceptional case.

<mike
 
P

Paolino

Mike said:
I have a list with some strings in in it, 'one', 'two' 'three' and so
on. I would like to add lists to a class with those names. I have no
way of knowing what will be in the list or how long the list will be in
advance.


Others have told you how to do it. Now I'm going to tell you why you
shouldn't.

First, since you don't know the names of the attributes you added, you
can't possibly write code that references them in the normal way. So
is there really much point in making them an attribute at all?

Second, since you don't know the names of the attributes you added,
you don't know if one of more of them is going to clobber a feafure of
the class that you want to use for something else. I.e., consider:


... pass
...

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'str' object is not callable


I.e. - if someone adds a __str__ attribute to your class, you won't be
able to print it any more. Not a good thing.

In general, you probably want a dictionary instead of attributes:


... def __init__(self, l):
... for i in l:
... self = []
...
c = C(['a', 'b', 'c'])
c['a']

[]

and 2c more to use attributes but prevent overriding of real attributes

def __getattr__(self,name):
if name in self:
return self[name]
raise AttributeError

Paolino





___________________________________
Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
http://mail.yahoo.it
 
B

BBands

That's interesting and I take your point. Maybe there is a better way.
Here is what I am doing now. (working)

I start with a text file of ticker symbols. I read each symbol and
stick it in a list, retrieve the data for it from MySQL, do a trivial
smoothing and pass the data to a modeling routine. I read the tickers
into a list, self.symbols. Then for each ticker I create a list,
self._0, self._1, ... and a list for the smoothed values,
self._0_smooth, self._1_smooth, ... I end up with data I can access
with self.__dict__["_" + str(var)] and a matching symbol which I can
access self.symbols[var].

Ideas for a better approach gladly accepted.

jab
 
B

BBands

That's interesting and I take your point. Maybe there is a better way.
Here is what I am doing now. (working)

I start with a text file of ticker symbols. I read each symbol and
stick it in a list, retrieve the data for it from MySQL, do a trivial
smoothing and pass the data to a modeling routine. I read the tickers
into a list, self.symbols. Then for each ticker I create a list,
self._0, self._1, ... and a list for the smoothed values,
self._0_smooth, self._1_smooth, ... I end up with data I can access
with self.__dict__["_" + str(var)] and a matching symbol which I can
access self.symbols[var].

Ideas for a better approach gladly accepted.

jab
 
M

Michael Hoffman

BBands said:
I start with a text file of ticker symbols. I read each symbol and
stick it in a list, retrieve the data for it from MySQL, do a trivial
smoothing and pass the data to a modeling routine. I read the tickers
into a list, self.symbols.
OK...

> Then for each ticker I create a list,
self._0, self._1, ...

That's not a list. That's a bunch of attributes.
I end up with data I can access
with self.__dict__["_" + str(var)] and a matching symbol which I can
access self.symbols[var]. Ideas for a better approach gladly accepted.

Why don't you use a real list instead? I don't understand what
self.__dict__["_" + str(var)] gets you.

self.symbols = ["IBM", "MSFT", "SCOX"]
self.values = [99, 100, 0.25]
self.smooth_values = [100, 100, 0]

or you could use a dict:

self.values = dict(IBM=99, MSFT=100, SCOX=0.25)
 
B

BBands

Why don't you use a real list instead?

I am using lists... I just showed the naming schema. Here is how they
are implemented.

for var in range(len(self.symbols)):
setattr(self, "_" + str(var), [])
I don't understand what
self.__dict__["_" + str(var)] gets you.

It let's me access lists that aren't known at write time.

jab
 
M

Mike Meyer

BBands said:
Why don't you use a real list instead?

I am using lists... I just showed the naming schema. Here is how they
are implemented.

for var in range(len(self.symbols)):
setattr(self, "_" + str(var), [])

That's not the list he's talking about. And I agree with him.

Why are you setting the attreibutes "_" + str(var)? Why not just store
them in a dictionary?
I don't understand what
self.__dict__["_" + str(var)] gets you.
It let's me access lists that aren't known at write time.

Yes, but it's ugly, makes one address space server for two different
sets of variables, and has potential for some nasty bugs. Why not just
do:

self.lists[var] = []

Or, if you're really tied to "_", do:

self._[var] = []

Or, given that your example used increasing numeric names, just use a
list here:

self._.append([])

which you would then reference as self._[0], self._[1], etc.

<mike
 
M

Mike Meyer

Paolino said:
Mike said:
BBands said:
I have a list with some strings in in it, 'one', 'two' 'three' and so
on. I would like to add lists to a class with those names. I have no
way of knowing what will be in the list or how long the list will be in
advance.
Others have told you how to do it. Now I'm going to tell you why you
shouldn't.
First, since you don't know the names of the attributes you added,
you
can't possibly write code that references them in the normal way. So
is there really much point in making them an attribute at all?
Second, since you don't know the names of the attributes you added,
you don't know if one of more of them is going to clobber a feafure of
the class that you want to use for something else. I.e., consider:
... pass
...
c = C()
print c
c.__str__ = 'foo'
print c
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'str' object is not callable
I.e. - if someone adds a __str__ attribute to your class, you won't
be
able to print it any more. Not a good thing.
In general, you probably want a dictionary instead of attributes:
class C(dict):
... def __init__(self, l):
... for i in l:
... self = []
...
c = C(['a', 'b', 'c'])
c['a']
[]

and 2c more to use attributes but prevent overriding of real attributes

def __getattr__(self,name):
if name in self:
return self[name]
raise AttributeError


Good point. The problem with this is that your real attributes will
now hide things stored in the dictionary. The bugs I listed above are
all caused by trying to conflate two different name spaces: the
attributes of the object and the variables stored in it as
data. Separating them out and then layering one back on top of the
other just gives you those bugs back.

<mike
 

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,266
Messages
2,571,318
Members
48,002
Latest member
EttaPfeffe

Latest Threads

Top