python classes

  • Thread starter William D. Gill
  • Start date
W

William D. Gill

I'm new to python and am probably trying too many new things at once, but
here goes.

I am working with a (MySQL) database and am trying to make a html /python
interface for editing records.
Data is broken up into several tables, and related by customer number. For
example one table contains basic information about the customer, one table
phone numbers (one record for published number, one for cell phone, etc,
all customers will have at least one record here).

I want to use python classes in my code so I have a couple of questions
about python classes:

1) can a class __init__ have multiple "signatures like in C++ i.e.
MyClass( int, string), . MyClass(int) ?
2) can a class attribute be an instance of another class or is multiple
inheritance the proper answer?
3) Can I make instantiation fail if an invalid customer number is use, and
wrap the "a=MyClass(cusid=999) in an exception?

Thanks in advance,

Bill
 
P

Peter Otten

William said:
I'm new to python and am probably trying too many new things at once, but
here goes.
Welcome!

I am working with a (MySQL) database and am trying to make a html /python
interface for editing records.
Data is broken up into several tables, and related by customer number.
For example one table contains basic information about the customer, one
table phone numbers (one record for published number, one for cell phone,
etc, all customers will have at least one record here).

I want to use python classes in my code so I have a couple of questions
about python classes:

1) can a class __init__ have multiple "signatures like in C++ i.e.
MyClass( int, string), . MyClass(int) ?

No, but you can provide defaults:
.... def __init__(self, mandatory, value=99, name="unknown"): pass
....<__main__.MyClass instance at 0x40290a4c>

and so on ad infinitum.
2) can a class attribute be an instance of another class ...

Yes, it can.
or is multiple inheritance the proper answer?

If the _question_ is 42?, then I would say so :)
3) Can I make instantiation fail if an invalid customer number is use, and
wrap the "a=MyClass(cusid=999) in an exception?

You _should_ raise a custom exception (just derive from Exception) which can
be loaded with arbitrary information - in your example that would rather be
the bad customer id than the inconsistant MyClass instance.


Peter
 
W

William D. Gill

Peter Otten said:
No, but you can provide defaults:

... def __init__(self, mandatory, value=99, name="unknown"): pass
...
<__main__.MyClass instance at 0x40290a4c>

and so on ad infinitum.
I'm not sure defaults do what I want. In C++ I could create an instance
passing customer id , or the name, have the constructor interrogat the db
and create the same resulting object.
I could use default id = None, name = None, and have the constructor
either name, id , or a "no info given" to determine how to create the
object.
Yes, it can.


If the _question_ is 42?, then I would say so :)

the _question_ is:
which of the following is correct?

class MyClass:
def __init__(self, id=0000):
self.data = MyOtherClass(id) # data is an object with name, id
and other properties

or

class MyClass(MyOtherClass)
def __init__(self, id=0000):
#self.data.id, self.data.name, and other properties are defined in
MyOtherClass and inherited in MyClass
You _should_ raise a custom exception (just derive from Exception) which can
be loaded with arbitrary information - in your example that would rather be
the bad customer id than the inconsistant MyClass instance.

I'm not sure I understand? I don't want python to create an instance if
given invalid data (i.e given an invalid id the db lookup will fail), and I
want to raise an exception when this happens.
 
P

Peter Otten

William said:
I could use default id = None, name = None, and have the constructor
either name, id , or a "no info given" to determine how to create the
object.

That's exactly what I'd do. An alternative would be to use factory functions
(which could be static or class methods), e. g.

class Customer:
def __init__(self, **kw):
self.__dict__.update(kw)
def fromId(id):
# look up data in db
if notFound:
raise InvalidCustomer(id)
return Customer(...)
fromId = staticmethod(fromId)
def fromName(name):
# look up data in db
return Customer(...)
fromName = staticmethod(fromName)
which of the following is correct?

class MyClass:
def __init__(self, id=0000):
self.data = MyOtherClass(id) # data is an object with name, id
and other properties

I think this is an extra complication that gains you nothing. The only
exception would be that data would not be initialized in MyClass.__init__()
but lazily at some later point, a usefull pattern if for a significant part
of the MyClass instances you can get away with not initializing data at
all. You would then change MyClass as follows:

MyClass(object):
def __init__(self, id):
self.id = id
self._data = None
def getdata(self):
if not self._data:
self._data = MyOtherClass(self.id)
return self._data
data = property(getdata)

class MyClass(MyOtherClass)
def __init__(self, id=0000):
#self.data.id, self.data.name, and other properties are defined
#in
MyOtherClass and inherited in MyClass

From what you've shown so far it's not clear to me why you need MyOtherClass
at all. In Python, attributes come at practically no cost, just say, e. g.
myClass.departmentId = 1234. Therefore inheritance would only be useful if
you want to reuse methods. Just think of Python classes as if they
inherited from an infinite number of abstract base classes. A simple
example: in most cases you can replace a file instance with any object that
provides a write(str) method.
I'm not sure I understand? I don't want python to create an instance if
given invalid data (i.e given an invalid id the db lookup will fail), and
I want to raise an exception when this happens.

I suppose that was a mutual misunderstanding. Did you mean this by
"wrapping"?

try:
customer = Customer.fromId(1234)
except InvalidCustomer, e:
print e

That's fine with me (I read wrapping as making the Customer instance an
attribute of the exception)


Peter
 
W

William D. Gill

Peter Otten said:
William D. Gill wrote:


I think this is an extra complication that gains you nothing. The only
exception would be that data would not be initialized in MyClass.__init__()
but lazily at some later point, a usefull pattern if for a significant part
of the MyClass instances you can get away with not initializing data at
all. You would then change MyClass as follows:
My thinking was to create a class for each table that contains pieces of the
whole customer information , and wrap OOPS! I mean include :) those classes
in the overall customer class object. That way by supplying id, all the
different constructors would go get the right data.

At my level (pre-novice) it's probably better to use one customer class and
sequential programming in the constructor:

select * from table A where id=1234
self.company_name = A.name
....

select * from table B where id=1234
self.mailto=B.mailto
self.billto = B.billto
....
select * from table C where id=1234
self.cell=C.cell
self.list=C.list
....
(using multiple selects because they may produce different size record sets)


I suppose that was a mutual misunderstanding. Did you mean this by
"wrapping"?

try:
customer = Customer.fromId(1234)
except InvalidCustomer, e:
print e
Yes


Thanks,
Bill
 

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

Similar Threads


Members online

Forum statistics

Threads
474,183
Messages
2,570,969
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top