best way to get data into a new instance?

J

John Salerno

Let's pretend I'm creating an Employee class, which I will later
subclass for more specific jobs. Each instance will have stuff like a
name, title, degrees held, etc. etc.

So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

Does a question like this depend on how the class will be used? I'm
trying to construct it in a way that is independent of, say, the GUI
interface that will be used, but I can't help but think that if all the
data is entered into a GUI, then passed programmatically to the class,
then it's no big deal because it happens behind the scenes. But if, for
instance, someone manually created a new instance, they would have a ton
of arguments to type in each time. Granted, even with the GUI they are
basically typing in arguments, but in the manual case you'd have to type
in the call to the class, the parentheses, commas, quotes around the
strings, etc. (But still, I'm trying not to let a specific interface
influence the construction of what should probably be a completely
independent class implementation.)

Thanks.
 
D

Diez B. Roggisch

John said:
Let's pretend I'm creating an Employee class, which I will later
subclass for more specific jobs. Each instance will have stuff like a
name, title, degrees held, etc. etc.

So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

Does a question like this depend on how the class will be used? I'm
trying to construct it in a way that is independent of, say, the GUI
interface that will be used, but I can't help but think that if all the
data is entered into a GUI, then passed programmatically to the class,
then it's no big deal because it happens behind the scenes. But if, for
instance, someone manually created a new instance, they would have a ton
of arguments to type in each time. Granted, even with the GUI they are
basically typing in arguments, but in the manual case you'd have to type
in the call to the class, the parentheses, commas, quotes around the
strings, etc. (But still, I'm trying not to let a specific interface
influence the construction of what should probably be a completely
independent class implementation.)

Who is typing?

The programmer is responsible for the construction of new instances (or
at least the code which will do that), and a constructor should contain
parameters for at least the values you absolutely expect to be there -
for example name and age or something like that in your example.

You can of course always add attributes later.

Diez
 
T

tobiah

So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

As was pointed out, you might ask that absolutely essential information
be passed to the constructor such as employee id#, but other then
that, I think that it is more usual to do:

class Employee:

__init__(self, id):
self.id = id

e = Employee(32445)

.... later


e.firstname = 'foo'
e.lastname = 'bar'

.... more as the information comes about.
 
F

Fredrik Lundh

John said:
So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

really long __init__ argument lists only work if most argument have
reasonable defaults, and you're prepared to use keyword arguments when
creating the objects. and don't mind writing the field names over and
over and over and over again.

really long positional argument lists are really bad; it's way too easy
to mess up the order, and end up stuffing the wrong thing in the wrong
field.

there's no need to use this if you're using the class as a "record";
just set the relevant attributes and be done with it.

(see the "simulate UI" part of my code example for how to do that).

</F>
 
B

Bruno Desthuilliers

John said:
Let's pretend I'm creating an Employee class, which I will later
subclass for more specific jobs.

Let's pretend it might be a good design... said:
Each instance will have stuff like a
name, title, degrees held, etc. etc.

So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

what about optional arguments ?

class Employee(object):
def __init__(self, id, name, **kw):
self.id = id
self.name = name
self.titles = kw.get('titles', [])
self.birthdate = kw.get(birthdate, None)
# etc
Does a question like this depend on how the class will be used?

I don't think it would make sens to design anything without any hint
about how it's supposed to be used.

My 2 cents
 
J

John Salerno

John said:
Let's pretend I'm creating an Employee class, which I will later
subclass for more specific jobs. Each instance will have stuff like a
name, title, degrees held, etc. etc.

So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

Does a question like this depend on how the class will be used? I'm
trying to construct it in a way that is independent of, say, the GUI
interface that will be used, but I can't help but think that if all the
data is entered into a GUI, then passed programmatically to the class,
then it's no big deal because it happens behind the scenes. But if, for
instance, someone manually created a new instance, they would have a ton
of arguments to type in each time. Granted, even with the GUI they are
basically typing in arguments, but in the manual case you'd have to type
in the call to the class, the parentheses, commas, quotes around the
strings, etc. (But still, I'm trying not to let a specific interface
influence the construction of what should probably be a completely
independent class implementation.)

Thanks.

Thanks again guys! I guess I'm letting all these little "getting
started" questions hang me up too much. I should just start coding like
Fredrik suggested ages ago and find out the bad design ideas for myself. :)

Right now I started messing around with designing the GUI that will be
used to input the data. It's much easier, I guess because it's just a
matter of *doing* and not really figuring things out, but that's also
why it gets tedious rather quickly!
 
J

James Stroud

John said:
Let's pretend I'm creating an Employee class, which I will later
subclass for more specific jobs. Each instance will have stuff like a
name, title, degrees held, etc. etc.

So I'm wondering, is the best way to get all this information into the
object to just have a really long __init__ method that takes each argument?

Does a question like this depend on how the class will be used? I'm
trying to construct it in a way that is independent of, say, the GUI
interface that will be used, but I can't help but think that if all the
data is entered into a GUI, then passed programmatically to the class,
then it's no big deal because it happens behind the scenes. But if, for
instance, someone manually created a new instance, they would have a ton
of arguments to type in each time. Granted, even with the GUI they are
basically typing in arguments, but in the manual case you'd have to type
in the call to the class, the parentheses, commas, quotes around the
strings, etc. (But still, I'm trying not to let a specific interface
influence the construction of what should probably be a completely
independent class implementation.)

Thanks.

This assumes that someone will hard-code an instance of your Employee. E.g.:

e = Employee(Last, First, ID,
private_medical_info = 'Has halitosis.')

Will this ever really happen--either by an API user or an end user?
Probably not for a database of any usefulness at all. Usually records
will be programatically created (or created through a gui), so it really
isn't necessary to worry about this case, except maybe for testing. This
has been my experience. Its probably better to init with the bare
minimum parameters and focus on how to move information from an external
source into an already created instance:

e = Employee(Last, First, ID)
e.private_medical_info = 'Has halitosis.'

If you are worried about validating field names, maybe use a method:

class Employee(object):
def __init__(self, Last, First, ID, **kwargs):
self.Last = Last
self.First = First
self.ID = ID
self._fields = {'Last':'Last Name',
'First':'First Name',
'ID':'Employee Identification Number',
'private_medical_info':'Any source of bad odor.'}
for (field, value) in kwargs.items():
self.set_value(field, value)
def set_value(field, value):
if not field in self._fields:
raise ValueError, 'Field "%s" not supported.' % field
else:
self.__setattr__(field, value)
def get_value(field):
if not field in self._fields:
raise ValueError, 'Field "%s" not supported.' % field
else:
self.__getattribute__(field)


OK, I'll stop. You get the idea.

You will find dealing with external sources the more interesting problem
anyway.

James


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

James Stroud

James said:
This assumes that someone will hard-code an instance of your Employee.
E.g.:

e = Employee(Last, First, ID,
private_medical_info = 'Has halitosis.')

Will this ever really happen--either by an API user or an end user?
Probably not for a database of any usefulness at all. Usually records
will be programatically created (or created through a gui), so it really
isn't necessary to worry about this case, except maybe for testing. This
has been my experience. Its probably better to init with the bare
minimum parameters and focus on how to move information from an external
source into an already created instance:

e = Employee(Last, First, ID)
e.private_medical_info = 'Has halitosis.'

If you are worried about validating field names, maybe use a method:

class Employee(object):
def __init__(self, Last, First, ID, **kwargs):
self.Last = Last
self.First = First
self.ID = ID
self._fields = {'Last':'Last Name',
'First':'First Name',
'ID':'Employee Identification Number',
'private_medical_info':'Any source of bad odor.'}
for (field, value) in kwargs.items():
self.set_value(field, value)
def set_value(field, value):
if not field in self._fields:
raise ValueError, 'Field "%s" not supported.' % field
else:
self.__setattr__(field, value)
def get_value(field):
if not field in self._fields:
raise ValueError, 'Field "%s" not supported.' % field
else:
self.__getattribute__(field)


OK, I'll stop. You get the idea.

You will find dealing with external sources the more interesting problem
anyway.

James
should be

def set_value(self, field, value):

and

def get_value(self, field):

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

John Machin

Diez said:
The programmer is responsible for the construction of new instances (or
at least the code which will do that), and a constructor should contain
parameters for at least the values you absolutely expect to be there -
for example name and age or something like that in your example.

Age? Absolutely expect?? Call me crazy, but I'd record the primary
information (date of birth), *if* available, and derive age on the fly
if possible if and only if needed.
 
M

Maxim Sloyko

tobiah wrote:
[snip]
class Employee:

__init__(self, id):
self.id = id

e = Employee(32445)

... later


e.firstname = 'foo'
e.lastname = 'bar'

... more as the information comes about.

Personally, I think that this is not a good solution. How would the
reader of your code guess what properties your object has? If you don't
like to write too many assignments, you can at least do something like
this:

def __init__(self, id, **kw):
self.id = id
for name in ['first_name', 'last_name', 'age', 'salary',
'whatever']:
self.__dict__[name] = kw.get(name, None)
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top