help with my first use of a class
Bruno Desthuilliers
onurb at xiludom.gro
Fri Oct 20 05:17:30 EDT 2006
BartlebyScrivener wrote:
> I am a mere hobbyist. Spent several hours trying to make a class,
> because I think this is an occasion where I need one. But I can't make
> it work.
>
> This code "works" (only because of the global c, which I know I'm
> supposed to avoid, by using a Class). I edited the rest to leave out
> the irrelevant formatting and printing of the quotations.
>
> I've read about Classes several times, but I don't "get" them yet.
Think of a class as both a "blueprint" for objects and a factory
creating these objects. The class lets you define the attributes and
behaviors of it's instances.
> Obviously. If I can solve one real life problem like this, then maybe
> I'll see the light.
>
> If I understand the power of Classes correctly, I could make one that
> would allow me to make a new instance that would connect to, say, an
> SQLite3 db instead of the Access db, as well as to create more methods
> that will do different SQL searches.
> Thank you for any help,
>
>
> import mx.ODBC.Windows as odbc
> import sys
> import random
>
> def connect():
> global c
> db='DSN=Quotations'
> conn = odbc.DriverConnect(db)
> c = conn.cursor()
>
> def random_quote():
> """
> Counts all of the quotes in MS Access database Quotations2005.mdb.
> Picks one quote at random and displays it using textwrap.
> """
> c.execute ("SELECT COUNT(Quote) FROM PythonQuoteQuery")
> # Yields the number of rows with something in the quote field
> total_quotes = c.fetchone()
> # Get a random number somewhere between 1 and the number of total
> quotes
> quote_number = (random.randint(1, total_quotes[0]),)
> # Select a quote where the ID matches that number
> c.execute ("SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?",
> quote_number)
> quote = c.fetchone()
> blah blah blah
>
> def print_quote()
> code to format and print the quote (which will also have to be
> global, unless I learn Classes!)
>
Ever wondered what arguments and return values were for ?-)
> if __name__ == '__main__':
> if len(sys.argv) == 1:
> connect()
> random_quote()
> print_quote()
>
First, notice that you *don't* need a class here to avoid globals.
Learning to use function as *functions* (ie: taking arguments and
returning values) instead of procedure would help:
def random_quote(cursor):
c.execute ("SELECT COUNT(Quote) FROM PythonQuoteQuery")
total_quotes = c.fetchone()
quote_number = (random.randint(1, total_quotes[0]),)
c.execute (
"SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?",
quote_number
)
return c.fetchone()
def format_quote(quote):
# code here
return formatted_quote
def main(*args):
if len(args) < 2:
print >> sys.stderr, "Missing dsn arg\nusage : %s dsn" % args[0]
return 1
dsn = args[1]
try:
conn = odbc.DriverConnect(dsn)
except <SomeODBCErrorHere>, e:
print >> sys.stderr "Cannot connect to %s : %s" % (dsn, e)
return 1
quote = random_quote(conn.cursor())
print format_quote(quote)
conn.close()
return 0
if __name__ == '__main__':
sys.exit(main(*sys.argv))
Now for an OO version - that won't buy you much IMHO:
class SQLFortune(object):
def __init__(self, dsn):
self._dsn = dsn
self._cnx = None
@apply
def connection():
def fget(self):
if self._cnx is None:
self._cnx = odbc.DriverConnect(self.dsn)
return self._cnx
def fset(self, _):
raise AttributeError("Attribute is read-only")
return property(**locals())
def random_quote(self):
c = self.connection.cursor()
c.execute ("SELECT COUNT(Quote) FROM PythonQuoteQuery")
total_quotes = c.fetchone()
quote_number = (random.randint(1, total_quotes[0]),)
c.execute (
"SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?",
quote_number
)
return c.fetchone()
def format_quote(self, quote):
# code here
return formatted_quote
def close(self):
try: self._cnx.close()
except: pass
def main(*args):
if len(args) < 2:
print >> sys.stderr, "Missing dsn arg\nusage : %s dsn" % args[0]
return 1
dsn = args[1]
fortune = SQLFortune(dsn)
print fortune.format_quote(fortune.random_quote())
fortune.close()
return 0
if __name__ == '__main__':
sys.exit(main(*sys.argv))
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list