Help needed - function apparently global cannot be called.

I

Ian Hobson

Hi all you experts,

This has me beat. Has anyone any ideas about what might be going wrong?

This is code from within a windows service (hence no print statements -
no sys.stdout to print on!).

I am trying to trace through to find where the code is not working. No
stdout so I have to log to a file.

I have the following code fragments.

def log(message):
f = open('d:\logfile.txt','a')
f.write(message + "\n")
f.close()

from DelNotePrinter import DelNotePrinter

note the order of the above - log is defined before the import.
Later in the source I have

log('disPrint is:'+disPrint)
log('count is:'+count)
log(repr(DelNotePrinter))
printer = DelNotePrinter(disPrint,int(count))

The DelNotePrinter.py file cannot us log even though it is declared
as global. The code is...

# coding=utf8
# DelNotePrinter = code to print delivery notes
assorted imports removed for space reasons

class DelNotePrinter(object):
''' Print Delivery Note on A5 in portrait '''
def __init__(self,printer,copies):
''' create printer and painter '''
global font,sm,log
log('DelNotePrinter: starting')
self.printer = QPrinter(QPrinter.HighResolution)
etc

The file the log writes contains..
disPrint is:HP Deskjet 6940 series
count is:1
<class 'DelNotePrinter.DelNotePrinter'>

The > is followed by a newline and end of file! Where is the
DelNotePrinter: starting message?

If I replace the opening of __init__ with
global font,sm,log
f = open('d:\logfile.txt','a')
f.write('DelNotePrinter: starting' + "\n")
f.close()
self.printer = QPrinter(QPrinter.HighResolution)

then the message IS written to the log file.

I have read http://docs.python.org/reference/simple_stmts.html#global
very carefully and I still don't understand.

Regards

Ian

p.s. There are no trackbacks, no events on the event log, and no error
messages I have been able to find. When run as a script (not a service)
DelNotePrinter does produce the expected printout.
 
B

Bruno Desthuilliers

Ian Hobson a écrit :
Hi all you experts,

This has me beat. Has anyone any ideas about what might be going wrong?

This is code from within a windows service (hence no print statements -
no sys.stdout to print on!).

I am trying to trace through to find where the code is not working. No
stdout so I have to log to a file.

Then you'd be better using the logging module from the stdlib. And FWIW,
you should try to make you code testable in a non-service context...
I have the following code fragments.

def log(message):
f = open('d:\logfile.txt','a')
f.write(message + "\n")
f.close()

from DelNotePrinter import DelNotePrinter

<OT>
The convention is to use all_lower_names for modules - having modules
and classes with the same (case-sensitive) name can be very misleading.
note the order of the above - log is defined before the import.

And ? Do you think it will affect the imported module in any way ? Like,
say, magically "inject" your log function in the DelNotePrinter module ?-)

Later in the source

Where ?
I have

log('disPrint is:'+disPrint)
log('count is:'+count)

Do yourself a favor and learn string formating...
log(repr(DelNotePrinter))
printer = DelNotePrinter(disPrint,int(count))

The DelNotePrinter.py file cannot us log even though it is declared
as global.

In Python, "global" means "module-level", and it's only necessary when
you want to rebind a module-level name from within a function or method.

The code is...
# coding=utf8
# DelNotePrinter = code to print delivery notes
assorted imports removed for space reasons

Some of these imports surely explain why you don't just get a NameError
when trying to call log() - wild guess : you have some "from xxx import
*" statement that does import another callable named 'log'.
class DelNotePrinter(object):
''' Print Delivery Note on A5 in portrait '''
def __init__(self,printer,copies):
''' create printer and painter '''
global font,sm,log
log('DelNotePrinter: starting')

self.printer = QPrinter(QPrinter.HighResolution)

If you want to access a name (function, class, whatever) defined in
another module, you have to explicitely import it.
The file the log writes contains..
disPrint is:HP Deskjet 6940 series
count is:1
<class 'DelNotePrinter.DelNotePrinter'>

The > is followed by a newline and end of file! Where is the
DelNotePrinter: starting message?

We can't tell - but you can get at least some hint, cf below
If I replace the opening of __init__ with
global font,sm,log
f = open('d:\logfile.txt','a')
f.write('DelNotePrinter: starting' + "\n")
f.close()
self.printer = QPrinter(QPrinter.HighResolution)

then the message IS written to the log file.

Obviously, yes. Now please add this to your code:

class DelNotePrinter(object):
''' Print Delivery Note on A5 in portrait '''
def __init__(self,printer,copies):
''' create printer and painter '''
global font,sm,log
f = open('d:\logfile.txt','a')
f.write('DelNotePrinter: starting' + "\n")

# check what "log" is bound to in the currrent namespace
f.write(
"DelNotePrinter : log is '%s' from '%s'" % (
log, log.__module__
))
f.close()
self.printer = QPrinter(QPrinter.HighResolution)

I have read http://docs.python.org/reference/simple_stmts.html#global
very carefully and I still don't understand.

The statement definition makes no sense if you don't understand
namespaces and bindings:

http://docs.python.org/reference/executionmodel.html#naming-and-binding
 
B

Bruno Desthuilliers

Ian Hobson a écrit :
(snip)

you may also want to read the recent "using modules" thread...
 
S

Stefan Schwarzer

Hi Ian,

f = open('d:\logfile.txt','a')

Just a note: Using a backslash in a non-raw string will get
you in trouble as soon as the backslash is followed by a
character which makes a special character sequence, like "\n".
For example,

f = open('d:\nice_filename.txt', 'a')

will give surprising results. :) Either double the
backslash, use a raw string, or, in the special case of
file system paths, possibly use a forward slash.

Stefan
 

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

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top