Simple Python class questions

J

John Dann

A Python newbie, but some basic understanding of how classes, objects
etc work in eg VB.Net. However, I'm struggling a little to translate
this knowledge into the Python context.

I'm trying to teach myself this aspect of Python by working up a trial
project, part of which calls for pulling in data from a serial data
connection at regular intervals. It looked sensible to place all the
comms procedures/functions in their own class and module and make
calls to those functions from an object instantiated in a main
controlling module. But I'm struggling to get this working - not sure
whether it's a fundamental misunderstanding of the use of classes in
Python, syntax errors pure and simple or, most likely, a combination
of both!

Maybe I could provide some outline code as an illustration:

Let's say I define the class in a module called comms.py. The class
isn't really going to inherit from any other class (except presumably
in the most primitive base-class sense, which is presumably automatic
and implicit in using the class keyword). Let's call the class
serial_link. So in comms.py I have:

class serial_link:
def __init__(self):
Try
Import serial # the pyserial library
Except ImportException
#Error handling

def openPort(self):
Try
#Code to try opening serial port
Return "Success"
Except SerialException
Return "Failure"

Then in my separate main calling module I might have:

Import comms
serlink=comms.seral_link #Create instance of serial_link class
print serlink.openPort


The last line I'm hoping would print Success or Failure. But I just
seem to get some internal reference to the openPort function enclosed
in <>.

So why doesn't it work please? I may be making multiple errors here
but as far as I can see the syntax seems right. For this particular
example, I don't need to pass any arguments from the
'seriallink.openPort' function so haven't included any parentheses (or
are they mandatory even if empty?) I could go on with the explanations
etc, but it may be simplest to see if anyone can spot a howler
straight out.

TIA for anyone willing to help
 
C

Cédric Lucantis

Le Thursday 19 June 2008 13:54:03 John Dann, vous avez écrit :
A Python newbie, but some basic understanding of how classes, objects
etc work in eg VB.Net. However, I'm struggling a little to translate
this knowledge into the Python context.

Maybe I could provide some outline code as an illustration:

Let's say I define the class in a module called comms.py. The class
isn't really going to inherit from any other class (except presumably
in the most primitive base-class sense, which is presumably automatic
and implicit in using the class keyword).

No it's not :) It is recommended to always use new-style classes, and thus to
give the object base explicitely :

class serial_link (object) :
...

see http://docs.python.org/ref/node33.html
print serlink.openPort

You just forgot the (), so you're printing the method object itself without
calling it : print serlink.openPort()
 
U

Ulrich Eckhardt

John said:
Let's say I define the class in a module called comms.py. The class
isn't really going to inherit from any other class (except presumably
in the most primitive base-class sense, which is presumably automatic
and implicit in using the class keyword). Let's call the class
serial_link. So in comms.py I have:

class serial_link:
def __init__(self):
Try
Import serial # the pyserial library

Stop, this can't work. Other than VB, Python actually is case sensitive, so
you must write 'try' and not 'Try' and also 'import' and not 'Import'.
Further, many (all?) statements that cause an indention are usually
terminated with a colon, so like with 'class ..:' and 'def ..:' you also
must use 'try:' and not just 'try'. Fix all these and try again, I guess
this will already help a lot.

One more thing: you are abusing exceptions. Typically, in such a short
program you only have one try-except pair in the main entry function and
all other code only throws the exceptions. In particular the __init__
function of a class should always signal errors using exceptions. However,
this is not a strict yes/no question but rather a stylistic one.


Uli
 
L

Lie

A Python newbie, but some basic understanding of how classes, objects
etc work in eg VB.Net. However, I'm struggling a little to translate
this knowledge into the Python context.

I'm trying to teach myself this aspect of Python by working up a trial
project, part of which calls for pulling in data from a serial data
connection at regular intervals. It looked sensible to place all the
comms procedures/functions in their own class and module and make
calls to those functions from an object instantiated in a main
controlling module. But I'm struggling to get this working - not sure
whether it's a fundamental misunderstanding of the use of classes in
Python, syntax errors pure and simple or, most likely, a combination
of both!

Maybe I could provide some outline code as an illustration:

Let's say I define the class in a module called comms.py. The class
isn't really going to inherit from any other class (except presumably
in the most primitive base-class sense, which is presumably automatic
and implicit in using the class keyword). Let's call the class
serial_link. So in comms.py I have:

class serial_link:
        def __init__(self):
                Try
                        Import serial # the pyserial library
                Except ImportException
                        #Error handling

        def openPort(self):
                Try
                        #Code to try opening serial port
                        Return "Success"
                Except SerialException
                        Return "Failure"

Then in my separate main calling module I might have:

Import comms
serlink=comms.seral_link     #Create instance of serial_link class
print serlink.openPort

The last line I'm hoping would print Success or Failure. But I just
seem to get some internal reference to the openPort function enclosed
in <>.

So why doesn't it work please? I may be making multiple errors here
but as far as I can see the syntax seems right. For this particular
example, I don't need to pass any arguments from the
'seriallink.openPort' function so haven't included any parentheses (or
are they mandatory even if empty?) I could go on with the explanations
etc, but it may be simplest to see if anyone can spot a howler
straight out.

Yes they're mandatory even if there is no arguments, this is needed so
python can differentiate between calling function and passing function
objects.
 
J

John Dann

Many thanks for the speedy replies.

Le Thursday 19 June 2008 13:54:03 John Dann, vous avez écrit :

No it's not :) It is recommended to always use new-style classes, and thus to
give the object base explicitely :

class serial_link (object) :
...

Can I just confirm: between the parentheses should be the literal
'object' - ie (object) - you're not just using 'object' as a
placeholder where there should be a more specific class name or
object?

--------------

Stop, this can't work. Other than VB, Python actually is case sensitive, so
you must write 'try' and not 'Try' and also 'import' and not 'Import'.
Further, many (all?) statements that cause an indention are usually
terminated with a colon, so like with 'class ..:' and 'def ..:' you also
must use 'try:' and not just 'try'. Fix all these and try again, I guess
this will already help a lot.

Sorry - the original code was syntactically correct - I just re-keyed
it rather quickly for the original newsgroup post here, rather than
copy/paste a larger chunk. I'll try to be more careful with any future
posts.
One more thing: you are abusing exceptions. Typically, in such a short
program you only have one try-except pair in the main entry function and
all other code only throws the exceptions. In particular the __init__
function of a class should always signal errors using exceptions. However,
this is not a strict yes/no question but rather a stylistic one.

Thanks - I need to think more clearly about the best way of doing
this.

JGD
 
C

Cédric Lucantis

Le Thursday 19 June 2008 15:13:39 John Dann, vous avez écrit :
Many thanks for the speedy replies.



Can I just confirm: between the parentheses should be the literal
'object' - ie (object) - you're not just using 'object' as a
placeholder where there should be a more specific class name or
object?

Right. 'object' is a builtin python class, used as a base for all classes as
in many OO languages.
 
L

Lie

Stop, this can't work. Other than VB, Python actually is case sensitive, so
you must write 'try' and not 'Try' and also 'import' and not 'Import'.
Further, many (all?) statements that cause an indention are usually
terminated with a colon, so like with 'class ..:' and 'def ..:' you also
must use 'try:' and not just 'try'. Fix all these and try again, I guess
this will already help a lot.

One more thing: you are abusing exceptions. Typically, in such a short
program you only have one try-except pair in the main entry function and
all other code only throws the exceptions. In particular the __init__
function of a class should always signal errors using exceptions. However,
this is not a strict yes/no question but rather a stylistic one.

Uli

I think it's not that hard to see that it's just a pseudo code
 
U

Ulrich Eckhardt

Lie said:
I think it's not that hard to see that it's just a pseudo code

"...in comms.py I have: ..." actually explicitly says that it is actual code
from a file.

*shrug*

Uli
 
T

Terry Reedy

John said:
Let's say I define the class in a module called comms.py. The class
isn't really going to inherit from any other class (except presumably
in the most primitive base-class sense, which is presumably automatic
and implicit in using the class keyword). Let's call the class
serial_link. So in comms.py I have:

If you on only ever going to have 1 serial link, you could put all
functions in the module. But the class allows for multiple links in
some future usage.
class serial_link:

Recommended for class names would be SerialLink, I believe (see PEP 8)
but at least a cap for the initial letter of python-defined classes.
def __init__(self):
Try
Import serial # the pyserial library
Except ImportException
#Error handling

The import should be at module level. You only want to do it once, not
for every link. And if the import fails, you should find out right
away. You perhaps should move try/except into the importing module. Or
re-raise the exception. Either way, the import of this module should
fail if it cannot get serial.
def openPort(self):
Try
#Code to try opening serial port
Return "Success"
Except SerialException
Return "Failure"

I would either move this to __init__ or call it from there (but the
latter only if you expect to close and reopen ports.

Then in my separate main calling module I might have:

Import comms

I guess you learned by now why cut/paste/edit-down is superior to
re-typing ;-)
serlink=comms.seral_link

.....()

#Create instance of serial_link class
print serlink.openPort

.....()

Terry Jan Reedy
 
J

John Dann

Many thanks for the further comments:

The import should be at module level. You only want to do it once, not
for every link. And if the import fails, you should find out right
away.

Yes I was wondering about that, but I wasn't clear about when 'body'
code (ie not contained within a def block) in the module might run
under Python. So it seemed to be safer to place the import statement
inside the 'constructor' to get the earliest warning of non-visibility
of pyserial. But you seem to be implying that the body code will run
when the class is instantiated - have I understood that right? It
surely doesn't run when the module containing the class is imported
into the main module - does it?? It would certainly make life easier
to place the import in the body of the module.

I think that some of the other points hinge on the this one, so let me
get my understanding straight on that first!
I guess you learned by now why cut/paste/edit-down is superior to
re-typing ;-)

Well I know what you mean, but actually in this instance my Python
environment is a non-networked laptop , so no easy way to cut and
paste to a networked PC! (Actually the laptop does have an Ethernet
chip in but bizarrely the driver somehow manages to kill my ADSL
connection at the exchange or ISP, which takes hours to reset so I
take care not to use this option. But learning Linux/Python is a
useful role for this otherwise defunct PC)

JGD
 
C

cokofreedom

Yes I was wondering about that, but I wasn't clear about when 'body'
code (ie not contained within a def block) in the module might run
under Python. So it seemed to be safer to place the import statement
inside the 'constructor' to get the earliest warning of non-visibility
of pyserial. But you seem to be implying that the body code will run
when the class is instantiated - have I understood that right? It
surely doesn't run when the module containing the class is imported
into the main module - does it?? It would certainly make life easier
to place the import in the body of the module.

Without insulting your intelligence I would advise looking at a few
python tutorials, not so much for the programming technique, but
rather how to think pythonic. A good one for using when coming from a
previous programming language is
Dive Into Python. http://www.diveintopython.org/

It does not deal with Serial specifically, but shows good examples of
practises in Python. Might be of benefit to you, and is very easy and
quick to read. :)
 
L

Lie

"...in comms.py I have: ..." actually explicitly says that it is actual code
from a file.

*shrug*

Uli

I'm not sure how you think saying 'in comms.py I have:' is an explicit
declaration that it is the very code in his comms.py, on contrary, he
said: '...provide some outline code as an illustration: ', but let's
stop polluting this thread.
 

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,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top