Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Class or Dictionary? (http://www.velocityreviews.com/forums/t743393-class-or-dictionary.html)

Martin De Kauwe 02-11-2011 02:56 PM

Class or Dictionary?
 
Hi,

I have a series of parameter values which i need to pass throughout my
code (>100), in C I would use a structure for example. However in
python it is not clear to me if it would be better to use a dictionary
or build a class object? Personally I think accessing the values is
neater (visually) with an object rather than a dictionary, e.g.

x = params['price_of_cats'] * params['price_of_elephants']

vs.

x = params.price_of_cats * params.price_of_elephants

So currently I am building a series of class objects to hold different
parameters and then passing these through my code, e.g.

class EmptyObject:
pass

self.animal_prices = EmptyObject()
self.price_of_cats = 12 or reading a file and populating the object


I would be keen to hear any reasons why this is a bad approach (if it
is, I haven't managed to work this out)? Or perhaps there is a better
one?

thanks

Martin

Andrea Crotti 02-11-2011 03:40 PM

Re: Class or Dictionary?
 
On Feb 11, 3:56*pm, Martin De Kauwe <mdeka...@gmail.com> wrote:
> Hi,
>
> I have a series of parameter values which i need to pass throughout my
> code (>100), in C I would use a structure for example. However in
> python it is not clear to me if it would be better to use a dictionary
> or build a class object? Personally I think accessing the values is
> neater (visually) with an object rather than a dictionary, e.g.
>
> x = params['price_of_cats'] * params['price_of_elephants']
>
> vs.
>
> x = params.price_of_cats * params.price_of_elephants


Visually neater is not really a good parameter to judge.
And in a class you can also overload __getattr__ to get the same
syntax as a dictionary.
But (>100) parameters seems really a lot, are you sure you can't split
in many classes instead?

Classes have also the advantage that you can do many things behind the
scenes, while with plain dictionaries you can't do much...
Where do you take those parameters from and what are they used for?

Martin De Kauwe 02-11-2011 04:01 PM

Re: Class or Dictionary?
 
On Feb 12, 2:40*am, Andrea Crotti <andrea.crott...@gmail.com> wrote:
> On Feb 11, 3:56*pm, Martin De Kauwe <mdeka...@gmail.com> wrote:
>
> > Hi,

>
> > I have a series of parameter values which i need to pass throughout my
> > code (>100), in C I would use a structure for example. However in
> > python it is not clear to me if it would be better to use a dictionary
> > or build a class object? Personally I think accessing the values is
> > neater (visually) with an object rather than a dictionary, e.g.

>
> > x = params['price_of_cats'] * params['price_of_elephants']

>
> > vs.

>
> > x = params.price_of_cats * params.price_of_elephants

>
> Visually neater is not really a good parameter to judge.


Yes and No. Makes the code easier to read and less picky to type out,
in my opinion! But regarding the "no" that is why I posted the
question

> And in a class you can also overload __getattr__ to get the same
> syntax as a dictionary.
> But (>100) parameters seems really a lot, are you sure you can't split
> in many classes instead?


i have a number some are smaller, for example switch/control flags.
But the rest can be quite large. I can split them but I don't see the
advantage particularly. Currently by using them (e.g.
params.rate_of_decomp) it clearly distinguishes in the code this was a
model parameter read in from a file. I could create more categories
but it just means more names to remember and change in the code.

>
> Classes have also the advantage that you can do many things behind the
> scenes, while with plain dictionaries you can't do much...
> Where do you take those parameters from and what are they used for?


I have a big model which calculates a process, but this is made up of
a number of smaller models. I have coded each of these are separate
classes which expect to receive an object e.g. params, or two objects
e.g. params and switches.

thanks

Bill Felton 02-11-2011 05:02 PM

Re: Class or Dictionary?
 
From an old-time Smalltalker / object guy, take this for whatever it's worth.
The *primary* reason for going with a class over a dictionary is if there is specific behavior that goes along with these attributes.
If there isn't, if this is "just" an 'object store', there's no reason not to use a dictionary.
After all, it is not too far off the mark to say a class is just a dictionary with it's own behavior set...
As another poster pointed out, 100 (or more) attributes is an oddity, I would call it a 'code smell'. Whereas a dictionary with 100 entries is no big deal at all.
But for me, the big deciding factor comes down to whether or not there is specific behavior associated with this "bundle" of attributes. If yes, class, if no, nothing wrong with dictionary.

cheers,
Bill
On Feb 11, 2011, at 9:56 AM, Martin De Kauwe wrote:

> Hi,
>
> I have a series of parameter values which i need to pass throughout my
> code (>100), in C I would use a structure for example. However in
> python it is not clear to me if it would be better to use a dictionary
> or build a class object? Personally I think accessing the values is
> neater (visually) with an object rather than a dictionary, e.g.
>
> x = params['price_of_cats'] * params['price_of_elephants']
>
> vs.
>
> x = params.price_of_cats * params.price_of_elephants
>
> So currently I am building a series of class objects to hold different
> parameters and then passing these through my code, e.g.
>
> class EmptyObject:
> pass
>
> self.animal_prices = EmptyObject()
> self.price_of_cats = 12 or reading a file and populating the object
>
>
> I would be keen to hear any reasons why this is a bad approach (if it
> is, I haven't managed to work this out)? Or perhaps there is a better
> one?
>
> thanks
>
> Martin
> --
> http://mail.python.org/mailman/listinfo/python-list



Dan Stromberg 02-11-2011 06:15 PM

Re: Class or Dictionary?
 
On Fri, Feb 11, 2011 at 6:56 AM, Martin De Kauwe <mdekauwe@gmail.com> wrote:
> Hi,
>
> I have a series of parameter values which i need to pass throughout my
> code (>100), in C I would use a structure for example. However in
> python it is not clear to me if it would be better to use a dictionary
> or build a class object? Personally I think accessing the values is
> neater (visually) with an object rather than a dictionary, e.g.
>
> x = params['price_of_cats'] * params['price_of_elephants']
>
> vs.
>
> x = params.price_of_cats * params.price_of_elephants
>
> So currently I am building a series of class objects to hold different
> parameters and then passing these through my code, e.g.
>
> class EmptyObject:
> * *pass
>
> self.animal_prices = EmptyObject()
> self.price_of_cats = 12 or reading a file and populating the object
>
>
> I would be keen to hear any reasons why this is a bad approach (if it
> is, I haven't managed to work this out)? Or perhaps there is a better
> one?


I'd use a class rather than a dictionary - because with a class,
pylint (and perhaps PyChecker and pyflakes?) should be able to detect
typos upfront. With a dictionary, typos remain runtime timebombs.

Terry Reedy 02-11-2011 06:32 PM

Re: Class or Dictionary?
 
or Module;-?

On 2/11/2011 9:56 AM, Martin De Kauwe wrote:
> Hi,
>
> I have a series of parameter values which i need to pass throughout my
> code (>100), in C I would use a structure for example. However in
> python it is not clear to me if it would be better to use a dictionary
> or build a class object? Personally I think accessing the values is
> neater (visually) with an object rather than a dictionary, e.g.


Dicts are, of course objects. That said, if all keys are identifier
strings, then attribute access is nicer. A module is essentially a dict
with all identifier keys, accessed as attributes.

mod.a is mod.__dict__['a']

Module are sometimes regarded as singleton data-only classes.
Just put 'import params' in every file that needs to read or write them.
The stdlib has at least a few modules that consist only of constants.
One example is tkinter.constants.

--
Terry Jan Reedy


Ethan Furman 02-11-2011 06:47 PM

Re: Class or Dictionary?
 
Andrea Crotti wrote:
> On Feb 11, 3:56 pm, Martin De Kauwe <mdeka...@gmail.com> wrote:
>> Hi,
>>
>> I have a series of parameter values which i need to pass throughout my
>> code (>100), in C I would use a structure for example. However in
>> python it is not clear to me if it would be better to use a dictionary
>> or build a class object? Personally I think accessing the values is
>> neater (visually) with an object rather than a dictionary, e.g.
>>
>> x = params['price_of_cats'] * params['price_of_elephants']
>>
>> vs.
>>
>> x = params.price_of_cats * params.price_of_elephants

>
> Visually neater is not really a good parameter to judge.


I strongly disagree. Code readability is one of the most important issues.

~Ethan~

Andrea Crotti 02-11-2011 07:27 PM

Re: Class or Dictionary?
 

Il giorno 11/feb/2011, alle ore 19.47, Ethan Furman ha scritto:

>
> I strongly disagree. Code readability is one of the most important issues.


Perfectly agree with that, but

obj.name = x
obj.surname = y

obj['name'] = x
obj['surname'] = y

are both quite readable in my opinion.
Other things are more important to evaluate in this case.

I normally always wrap dictionaries because before or later I'll want to add some other
features, but I don't know if that's the case here.

Jean-Michel Pichavant 02-11-2011 08:01 PM

Re: Class or Dictionary?
 
Martin De Kauwe wrote:
> Hi,
>
> I have a series of parameter values which i need to pass throughout my
> code (>100), in C I would use a structure for example. However in
> python it is not clear to me if it would be better to use a dictionary
> or build a class object? Personally I think accessing the values is
> neater (visually) with an object rather than a dictionary, e.g.
>
> x = params['price_of_cats'] * params['price_of_elephants']
>
> vs.
>
> x = params.price_of_cats * params.price_of_elephants
>
> So currently I am building a series of class objects to hold different
> parameters and then passing these through my code, e.g.
>
> class EmptyObject:
> pass
>
> self.animal_prices = EmptyObject()
> self.price_of_cats = 12 or reading a file and populating the object
>
>
> I would be keen to hear any reasons why this is a bad approach (if it
> is, I haven't managed to work this out)? Or perhaps there is a better
> one?
>
> thanks
>
> Martin
>

Using classes is the best choice.

However, if because there would be too much classes to define so that
you are forced to use your EmptyObject trick, adding attributes to the
inntance dynamically, I'd say that dictionnaries are a more common pattern.

Ideally, you would have something like:

class PriceHolder(object):
@classmethod
def fromFile(cls, filename):
# example of abstract method
pass

class Animals(PriceHolder):
def __init__(self):
self.cat = None
self.elephant = None

class Fruits(PriceHolder):
def __init__(self):
self.banana = None
self.apple = None


Then you would have to write 100 PriceHolder subclasses...

JM

Martin De Kauwe 02-11-2011 11:45 PM

Re: Class or Dictionary?
 
Hi,

yes I read a .INI file using ConfigParser, just similar sections (in
my opinion) to make one object which i can then pass to different
classes. E.G.

class Dict2Obj:
""" Turn a dictionary into an object.

The only purpose of this is that I think it is neater to reference
values
x.soiltemp rather than x['soiltemp'] ;P
"""
def __init__(self, dict):

for k, v in dict.items():
setattr(self, k, v)


class Parser(object):
""" Load up all the initialisation data.

Return the met data as an array, perhaps we should really also
return a
header as well? Return the ini file as various objects.

"""
def __init__(self, ini_fname, met_fname):

self.ini_fname = ini_fname
self.met_fname = met_fname

def load_files(self):

# read the driving data in, this may get more complicated?
met_data = met_data = np.loadtxt(self.met_fname, comments='#')

# read the configuration file into a different dicts, break up
# into model_params, control and state
config = ConfigParser.RawConfigParser()
config.read(self.ini_fname)

# params
model_params = {}
sections =
['water','nitra','soilp','carba','litter','envir',' prodn']
for section in sections:
for option in config.options(section):
model_params[option] = config.getfloat(section,
option)

# turn dict into an object
model_params = Dict2Obj(model_params)

# control
control = {}
for option in config.options('control'):
control[option] = config.getint('control', option)

# turn dict into an object
control = Dict2Obj(control)

initial_state = {}
sections = ['cinit','ninit','vinit']
for section in sections:
for option in config.options(section):
initial_state[option] = config.getfloat(section,
option)

# turn dict into objects
initial_state = Dict2Obj(initial_state)

return (initial_state, control, model_params,
met_data)

So I would then pass these objects through my code, for example a
given class would just expect to inherit params perhaps.

class calc_weight(object):

def __init__(self, params):
self.params = params

There are also "states" that evolve through the code which various
methods of a given class change. For example lets call it elephants
weight. So the model will do various things to predict changes in our
elephants weight, so there will be a class to calculate his/her food
intake etc. Using this example the other thing I wanted to do was pass
"states" around like self.elephant_weight. However it occurred to me
if I just used self.elephant_weight for example it would make it
harder to call individual components seperately, so better to stick to
the same method and using an object i reasoned. Hence I started with
my emptydict thing, I hope that helps make it clearer?

class EmptyObject:
pass


# generate some objects to store pools and fluxes...
self.pools = EmptyObject()

# add stuff to it
self.pools.elephant_weight = 12.0

thanks for all of the suggestions it is very insightful


All times are GMT. The time now is 05:57 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.