471,873 Members | 1,858 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,873 software developers and data experts.

Simple Python class questions

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
Jun 27 '08 #1
13 1977
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()

--
Cédric Lucantis
Jun 27 '08 #2
Lie
On Jun 19, 6:54*pm, John Dann <n...@prodata.co.ukwrote:
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.
TIA for anyone willing to help
Jun 27 '08 #3
John Dann wrote:
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

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

Jun 27 '08 #4
Many thanks for the speedy replies.

On Thu, 19 Jun 2008 14:14:02 +0200, Cédric Lucantis <om**@no-log.org>
wrote:
>Le Thursday 19 June 2008 13:54:03 John Dann, vous avez écrit*:
>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) :
...
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?

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

On Thu, 19 Jun 2008 14:21:46 +0200, Ulrich Eckhardt
<ec******@satorlaser.comwrote:
>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
Jun 27 '08 #5
Le Thursday 19 June 2008 15:13:39 John Dann, vous avez écrit*:
Many thanks for the speedy replies.

On Thu, 19 Jun 2008 14:14:02 +0200, Cédric Lucantis <om**@no-log.org>

wrote:
Le Thursday 19 June 2008 13:54:03 John Dann, vous avez écrit*:
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) :
...

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.

--
Cédric Lucantis
Jun 27 '08 #6
Lie
On Jun 19, 7:21*pm, Ulrich Eckhardt <eckha...@satorlaser.comwrote:
John Dann wrote:
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

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
I think it's not that hard to see that it's just a pseudo code
Jun 27 '08 #7
Lie wrote:
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
--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

Jun 27 '08 #8


John Dann wrote:
>
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

Jun 27 '08 #9
Many thanks for the further comments:

On Thu, 19 Jun 2008 21:24:31 -0400, Terry Reedy <tj*****@udel.edu>
wrote:
> def __init__(self):
Try
Import serial # the pyserial library
>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
Jun 27 '08 #10
>
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. :)
Jun 27 '08 #11
John Dann <ne**@prodata.co.ukwrote:
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.
Python starts executing at the top of your main script and then proceeds
line by line down until it falls off the bottom. Various things can
divert it from this straightforward progression towards the end of the
script, some of them such as if/for/while/raise or function calls are
obvious, but the less obvious ones include:

import somemodule (or 'from somemodule import something')

if 'somemodule' has not previously been imported this will find the
module and execute the lines of code in the module from top to bottom
just as for the main script. When it falls off the bottom of the module
it returns to the import statement, assigns the module or the imported
attributes to a name or names in the calling namespace (yes, an import
is just a highly specialised assignment statement), and then continues
with the next statement.

If somemodule has already started being imported anywhere in the program
then the import simply returns immediately and does the assignment.
(This can be a cause of confusion if you try to import modules
recursively as it is perfectly possible that the imported module has not
yet finished executing, so it may not yet have all the classes and
functions you expect).

class somename(bases):
somecode

A 'class' statement in Python is just executable code. The body of the
class is executed from top to bottom but in a new namespace. When
execution falls off the bottom of the class body a new class object is
created from that namespace and the base classes. The new class object
is then assigned to 'somename' (i.e. a class statement is a specialised
assignment statement). Then execution then procedes with the next
statement.

def functionname(arg1, arg2=default):
somecode

A 'def' statement in Python is also a specialised assignment statement:
unlike 'class' it doesn't immediately execute the code in the body, but
it does evaluate any default argument values when it encounters the
'def'. Then it creates a new function object from the code in the body
and the default arguments (and a few other things such as the argument
specification and the function name). Then it continues with the next
statement.

global name

The 'global' statement is not executed at runtime. It is the only Python
statement which is purely compile time.

Once you understand this it should be much clearer: everything except
global is executed when it is encountered following the normal rules for
program flow, and all the ways of creating module, classes, and
functions simply execute some code and then do an assignment (and so if
you wish you can later overwrite the values they assigned).

If you wish to do something special when an import fails then you simply
put try:..except: around the import at the top level in a module and
handle it there: you don't need to put either the import or the handler
inside a function.

--
Duncan Booth http://kupuguy.blogspot.com
Jun 27 '08 #12
Lie
On Jun 19, 10:49*pm, Ulrich Eckhardt <eckha...@satorlaser.comwrote:
Lie wrote:
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
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.
Jun 27 '08 #13
In article
<85**********************************@z16g2000prn. googlegroups.com>,
Lie <Li******@gmail.comwrote:
On Jun 19, 7:21*pm, Ulrich Eckhardt <eckha...@satorlaser.comwrote:
John Dann wrote:
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.
[...]

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

I think it's not that hard to see that it's just a pseudo code
I would have _thought_ it wasn't hard to see that if a person
says he's totally new to the language, and even explicitly says
that the problem could be syntax errors, then he shouldn't
post pseudo code. How in the world is pseudo code going to
allow people to help him fix his syntax?

--
David C. Ullrich
Jun 27 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Skip Montanaro | last post: by
1 post views Thread by David Bear | last post: by
30 posts views Thread by Brian Elmegaard | last post: by
9 posts views Thread by jezonthenet | last post: by
15 posts views Thread by Bjoern Schliessmann | last post: by
8 posts views Thread by Krypto | last post: by
17 posts views Thread by Chris M. Thomasson | last post: by
reply views Thread by YellowAndGreen | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.