log4py confusion
Greetings! I have finally gotten fed up with all of the Python scripts used in my company that have every parameter hard-coded. I am rewriting one of them to read all of its parameters from an XML file. Then, we can change the XML file to control which database it is using, whether its running in debug mode or not, and various other things. One of the parameters I want the XML file to contain is the name of the script's log file. I have a class named Settings that will contain all the parameters read from the XML file. But if something goes wrong, I want to log it. So, I want to have a Logger object for it to use. I use a hard-coded file name for that. Then, after reading the XML file, I want to create a second Logger object that will be used by the rest of the script. When I try to use the second Logger object, I get an exception complaining that 'unicode' object has no attribute 'write'. The script and the exception messages are below. Can anyone see what I'm doing wrong? Can anyone point me to a web site documenting the log4py module? Thank you very much. RobR import os import sys import string import win32api import win32event import win32com import win32com.client import win32net import pythoncom import time import log4py import xml.dom.minidom as minidom import argparse #Set to 1 to run loop once for debugging, set to 0 for operation #Debug = 1 class DataElement: value = None def __init__(self, element = None): if element != None: self.GetData(element) def GetData(self, element): nodes = element.childNodes for node in nodes: if node.nodeType == node.TEXT_NODE: self.value = node.data def GetDataFromRoot(self, rootElement, targetName, defaultValue): elements = rootElement.getElementsByTagName(targetName) if elements: dataElement = DataElement(elements[0]) if (dataElement): self.value = dataElement.value else: self.value = defaultValue else: self.Value = defaultValue def __nonzero__(self): return self.value != None class Settings: logFile = TaskToCrane_somethingnew.log def __init__(self): print I don't know what XML file to use yet. def __init__(self, fileName, tempLogger): tempLogger.info( Settings will come from + fileName) settingsDoc = minidom.parse(fileName) rootElement = settingsDoc.documentElement # print Root element name: + rootElement.tagName programControlElement = rootElement.getElementsByTagName(ProgramControl)[0] logFileElement = DataElement() logFileElement.GetDataFromRoot(programControlElement, LogFile, self.logFile) if logFileElement: self.logFile = logFileElement.value else: tempLogger.error(Failed to get log file name.) def Log(self, logger): logger.info(Log file: + str(self.logFile)) if __name__ == __main__ : TempLogger = log4py.Logger().get_instance(main) TempLogger.set_rotation(log4py.ROTATE_DAILY, 5) TempLogger.set_loglevel(log4py.LOGLEVEL_DEBUG) TempLogger.set_formatstring(%T - %L %M) TempLogger.set_target(TaskToCrane_logging_base.log) parser = argparse.ArgumentParser() parser.add_argument(settings_file) args = parser.parse_args() programSettings = Settings(args.settings_file, TempLogger) TempLogger.info(Setting actual log target to + programSettings.logFile) Logger = log4py.Logger().get_instance(main) Logger.set_rotation(log4py.ROTATE_DAILY, 5) Logger.set_loglevel(log4py.LOGLEVEL_DEBUG) Logger.set_formatstring(%T - %L %M) Logger.set_target(programSettings.logFile) programSettings.Log(TempLogger) Traceback (most recent call last): File D:\Python27\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py, line 322, in RunScript debugger.run(codeObject, __main__.__dict__, start_stepping=0) File D:\Python27\Lib\site-packages\pythonwin\pywin\debugger\__init__.py, line 60, in run _GetCurrentDebugger().run(cmd, globals,locals, start_stepping) File D:\Python27\Lib\site-packages\pythonwin\pywin\debugger\debugger.py, line 655, in run exec cmd in globals, locals File D:\Program Files\WinCaps\Scripts\TaskToCrane_logging.py, line 91, in module programSettings.Log(TempLogger) File D:\Program Files\WinCaps\Scripts\TaskToCrane_logging.py, line 66, in Log logger.info(Log file: + str(self.logFile)) File log4py.py, line 359, in info self.__Logger_showmessage(message, MSG_INFO) File log4py.py, line 534, in __Logger_showmessage target.write(%s\n % line) AttributeError: 'unicode' object h -- http://mail.python.org/mailman/listinfo/python-list
RE: log4py confusion
The last line, programSettings.Log(TempLogger), should have been programSettings.Log(Logger) I get the same error no matter which logger I use, though, which I don't understand. Also, I'm using Python 2.7. Thanks again for your help! RobR From: Python-list [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of Rob Richardson Sent: Thursday, December 13, 2012 1:58 PM To: python-list@python.org Subject: log4py confusion Greetings! I have finally gotten fed up with all of the Python scripts used in my company that have every parameter hard-coded. I am rewriting one of them to read all of its parameters from an XML file. Then, we can change the XML file to control which database it is using, whether its running in debug mode or not, and various other things. One of the parameters I want the XML file to contain is the name of the script's log file. I have a class named Settings that will contain all the parameters read from the XML file. But if something goes wrong, I want to log it. So, I want to have a Logger object for it to use. I use a hard-coded file name for that. Then, after reading the XML file, I want to create a second Logger object that will be used by the rest of the script. When I try to use the second Logger object, I get an exception complaining that 'unicode' object has no attribute 'write'. The script and the exception messages are below. Can anyone see what I'm doing wrong? Can anyone point me to a web site documenting the log4py module? Thank you very much. RobR import os import sys import string import win32api import win32event import win32com import win32com.client import win32net import pythoncom import time import log4py import xml.dom.minidom as minidom import argparse #Set to 1 to run loop once for debugging, set to 0 for operation #Debug = 1 class DataElement: value = None def __init__(self, element = None): if element != None: self.GetData(element) def GetData(self, element): nodes = element.childNodes for node in nodes: if node.nodeType == node.TEXT_NODE: self.value = node.data def GetDataFromRoot(self, rootElement, targetName, defaultValue): elements = rootElement.getElementsByTagName(targetName) if elements: dataElement = DataElement(elements[0]) if (dataElement): self.value = dataElement.value else: self.value = defaultValue else: self.Value = defaultValue def __nonzero__(self): return self.value != None class Settings: logFile = TaskToCrane_somethingnew.log def __init__(self): print I don't know what XML file to use yet. def __init__(self, fileName, tempLogger): tempLogger.info( Settings will come from + fileName) settingsDoc = minidom.parse(fileName) rootElement = settingsDoc.documentElement # print Root element name: + rootElement.tagName programControlElement = rootElement.getElementsByTagName(ProgramControl)[0] logFileElement = DataElement() logFileElement.GetDataFromRoot(programControlElement, LogFile, self.logFile) if logFileElement: self.logFile = logFileElement.value else: tempLogger.error(Failed to get log file name.) def Log(self, logger): logger.info(Log file: + str(self.logFile)) if __name__ == __main__ : TempLogger = log4py.Logger().get_instance(main) TempLogger.set_rotation(log4py.ROTATE_DAILY, 5) TempLogger.set_loglevel(log4py.LOGLEVEL_DEBUG) TempLogger.set_formatstring(%T - %L %M) TempLogger.set_target(TaskToCrane_logging_base.log) parser = argparse.ArgumentParser() parser.add_argument(settings_file) args = parser.parse_args() programSettings = Settings(args.settings_file, TempLogger) TempLogger.info(Setting actual log target to + programSettings.logFile) Logger = log4py.Logger().get_instance(main) Logger.set_rotation(log4py.ROTATE_DAILY, 5) Logger.set_loglevel(log4py.LOGLEVEL_DEBUG) Logger.set_formatstring(%T - %L %M) Logger.set_target(programSettings.logFile) programSettings.Log(TempLogger) Traceback (most recent call last): File D:\Python27\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py, line 322, in RunScript debugger.run(codeObject, __main__.__dict__, start_stepping=0) File D:\Python27\Lib\site-packages\pythonwin\pywin\debugger\__init__.py, line 60, in run _GetCurrentDebugger().run(cmd, globals,locals, start_stepping) File D:\Python27\Lib\site-packages\pythonwin\pywin\debugger\debugger.py, line 655, in run exec cmd in globals, locals File D:\Program Files\WinCaps\Scripts\TaskToCrane_logging.py, line 91, in module
RE: log4py confusion
Thanks for the suggestion, but I don't think that can be it. At least, it's not it on the line you specified. That form, with the target name given as a hard-coded string, is in use in every Python script our company uses. So, set_target() is expecting a file instead of a file name, there must be some implicit conversion going on that creates a file object of the given name before setting the log target to the file. On the other hand, it would certainly explain the 'Unicode' object does not have attribute 'write' message. A file object would be expected to have an attribute named 'write', while a string object wouldn't. The error happens after the target is changed to a file name contained in a variable. Why doesn't that implicit conversion work with a string contained in a variable? Do I have to do an explicit cast of some kind? Or, probably better, I should probably look up how to create a file object so I can pass it in to the set_target() function. That's one reason I asked for documentation on log4py: so I could see what methods are available, and what arguments they actually expect. Thanks again! RobR -Original Message- From: Python-list [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of MRAB Sent: Thursday, December 13, 2012 2:35 PM To: python-list@python.org Subject: Re: log4py confusion On 2012-12-13 18:58, Rob Richardson wrote: Greetings! I have finally gotten fed up with all of the Python scripts used in my company that have every parameter hard-coded. I am rewriting one of them to read all of its parameters from an XML file. Then, we can change the XML file to control which database it is using, whether its running in debug mode or not, and various other things. One of the parameters I want the XML file to contain is the name of the script's log file. I have a class named Settings that will contain all the parameters read from the XML file. But if something goes wrong, I want to log it. So, I want to have a Logger object for it to use. I use a hard-coded file name for that. Then, after reading the XML file, I want to create a second Logger object that will be used by the rest of the script. When I try to use the second Logger object, I get an exception complaining that 'unicode' object has no attribute 'write'. The script and the exception messages are below. Can anyone see what I'm doing wrong? [snip] I think the problem might be that it's expecting a file object, not a file name/path as you have here: TempLogger.set_target(TaskToCrane_logging_base.log) -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
RE: log4py confusion
I think I have the answer. All I need to do is use the str() function to convert the object stored in logFile from a Unicode string to a normal string: Logger.set_target(str(programSettings.logFile)) RobR -Original Message- From: Python-list [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of Rob Richardson Sent: Thursday, December 13, 2012 2:52 PM To: python-list@python.org Subject: RE: log4py confusion Thanks for the suggestion, but I don't think that can be it. At least, it's not it on the line you specified. That form, with the target name given as a hard-coded string, is in use in every Python script our company uses. So, set_target() is expecting a file instead of a file name, there must be some implicit conversion going on that creates a file object of the given name before setting the log target to the file. On the other hand, it would certainly explain the 'Unicode' object does not have attribute 'write' message. A file object would be expected to have an attribute named 'write', while a string object wouldn't. The error happens after the target is changed to a file name contained in a variable. Why doesn't that implicit conversion work with a string contained in a variable? Do I have to do an explicit cast of some kind? Or, probably better, I should probably look up how to create a file object so I can pass it in to the set_target() function. That's one reason I asked for documentation on log4py: so I could see what methods are available, and what arguments they actually expect. Thanks again! RobR -Original Message- From: Python-list [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of MRAB Sent: Thursday, December 13, 2012 2:35 PM To: python-list@python.org Subject: Re: log4py confusion On 2012-12-13 18:58, Rob Richardson wrote: Greetings! I have finally gotten fed up with all of the Python scripts used in my company that have every parameter hard-coded. I am rewriting one of them to read all of its parameters from an XML file. Then, we can change the XML file to control which database it is using, whether its running in debug mode or not, and various other things. One of the parameters I want the XML file to contain is the name of the script's log file. I have a class named Settings that will contain all the parameters read from the XML file. But if something goes wrong, I want to log it. So, I want to have a Logger object for it to use. I use a hard-coded file name for that. Then, after reading the XML file, I want to create a second Logger object that will be used by the rest of the script. When I try to use the second Logger object, I get an exception complaining that 'unicode' object has no attribute 'write'. The script and the exception messages are below. Can anyone see what I'm doing wrong? [snip] I think the problem might be that it's expecting a file object, not a file name/path as you have here: TempLogger.set_target(TaskToCrane_logging_base.log) -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
How do I find out what file an import is using?
I am trying to work with a Python script someone else wrote. The script includes the line from Level3Utils import * I need to look at the functions that are included in that import. In an effort to identify exactly which file is being used, I renamed the Level3Utils.py and Level3Utils.pyc files in the same folder as the script I'm working on. The import command in PythonWin executed without error. I looked for a file named Level3Utils.py in my Python tree (d:/Python25, in my case). None were there. I then commented out the import line and stepped through the code. It ran without error! The class that should have come from Level3Utils executed successfully without being imported! How do I find out where the class definition actually is? (There is no PYTHONPATH environmental variable defined on my machine.) Thanks very much! RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: How to stop the program as soon as one of the condition is met
Please show us your code. RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: The devolution of English language and slothful c.l.p behaviors exposed!
In America, they haven't spoken it for years! -- Professor Henry Higgins, My Fair Lady -Original Message- On 24/01/2012 05:57, Rick Johnson wrote: cut rant I would wish that pedantic citizens of the British colony in America stopped calling whatever misinterpreted waffle they produce, English. -- mph -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
PythonWin debugger holds onto global logging objects too long
I use PythonWin to debug the Python scripts we write. Our scripts often use the log2py logging package. When running the scripts inside the debugger, we seem to get one logging object for every time we run the script. The result is that after running the script five times, the log file contains five copies of every message. The only way I know to clean this up and get only a single copy of each message is to close PythonWin and restart it. What do I have to do in my scripts to clean up the logging objects so that I never get more than one copy of each message in my log files? Thank you very much! Rob Richardson -- http://mail.python.org/mailman/listinfo/python-list
RE: What replaces log4py under Python 3.2?
Thank you for that link. Our customers are used to the rotating log file capability of the log4py package. I did not see anything in that link that talks about rotating log files (changing file name when the date changes, and saving a limited number of old log files). Is that possible using the stdlib logging package? Is there something else available that will do that, so we don't have to roll our own (or, more likely, stick to Python 2.7, for which log4py works)? Thanks again! RobR -Original Message- From: python-list-bounces+rob.richardson=rad-con@python.org [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of Irmen de Jong Sent: Tuesday, November 22, 2011 2:41 PM To: python-list@python.org Subject: Re: What replaces log4py under Python 3.2? On 22-11-11 19:32, Rob Richardson wrote: Greetings! My company has been using the log4py library for a long time. A co-worker recently installed Python 3.2, and log4py will no longer compile. (OK, I know that's the wrong word, but you know what I mean.) What logging package should be used now? The logging module from Python's stdlib? http://docs.python.org/py3k/library/logging.html Irmen -Original Message- From: python-list-bounces+rob.richardson=rad-con@python.org [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of Irmen de Jong Sent: Tuesday, November 22, 2011 2:41 PM To: python-list@python.org Subject: Re: What replaces log4py under Python 3.2? On 22-11-11 19:32, Rob Richardson wrote: Greetings! My company has been using the log4py library for a long time. A co-worker recently installed Python 3.2, and log4py will no longer compile. (OK, I know that's the wrong word, but you know what I mean.) What logging package should be used now? The logging module from Python's stdlib? http://docs.python.org/py3k/library/logging.html Irmen -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
What replaces log4py under Python 3.2?
Greetings! My company has been using the log4py library for a long time. A co-worker recently installed Python 3.2, and log4py will no longer compile. (OK, I know that's the wrong word, but you know what I mean.) What logging package should be used now? Thank you. RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: Understanding def foo(*args)
My thanks both to the original poster and to JM for an excellent answer. I saw this syntax for the first time recently, and I've been curious about it too. RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: Help with code-lists and strings
Cathy, Please take another try at writing your program, using what advice you have received so far that you understand. I think this discussion is going rather far away from what you need, and seeing another step in the evolution of your program should help bring it back on track. I like your optimism! RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: Help with code-lists and strings
You take a sentence and break it up into words, storing it in a list named list. Then, for each word in the list, you set list2 to a boolean value of true or false, depending on the result of isupper() and istitle(). Note that the variable list2 does not refer to a list. It refers to whatever the result of the or operation is. Finally, you print out the word from the original, unordered list. You never do anything at all with list2. At least, that what I think is happening, but I am by no means a Python expert. Here's a suggestion: Try writing out what you want to do in plain English, but formatted sort of like a Python script would be. (This is generally called pseudocode. It looks like a computer language, but it isn't.) Once you've got that, use it as a framework to write your Python code. Good luck! RobR From: python-list-bounces+rob.richardson=rad-con@python.org [mailto:python-list-bounces+rob.richardson=rad-con@python.org] On Behalf Of Cathy James Sent: Wednesday, January 05, 2011 12:57 PM To: python-list@python.org Subject: Help with code-lists and strings Dear all, You folks will probably hear from me more often in the next few months. I hope some of you have time help me on occassion. Actually, a volunteer mentor would be greatly appreciated:) I am learning python and came across an excercise where i need to use lists to strip words from a sentence; starting with those containing one or more uppercase letters, followed by words with lower case letters. When I try, i get words in the order they were written:( I tried if statements, but unsuccessful. This has to be very easy to you experts, but I am clueless ( still rocket science to me) :( #Below is my shot at it: s=input(Write a sentence: ) list=s.strip().split() for word in list: list2 = (word.isupper() or word.istitle()) print (word) else print (word) -- http://mail.python.org/mailman/listinfo/python-list
RE: If/then style question
-Original Message- What about, def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode I reply - This is interesting, but I don't understand it (which speaks volumes about the level of my understanding of Python). First, just to clarify, I don't think the indentation I saw was what was originally posted. The else must be indented to match the if, and the two statements under else are in the else block. The return statement is indented at the same level as the for statement, so that it will be executed after the for loop exits. Correct? Now, the for loop will set condition to cond1 and exitCode to 'error1'. Then it checks the contents of the condition variable. But what does not variable_name by itself mean? I'm guessing that it checks that the variable refers to an object. So, the first time through, condition refers to cond1, the if condition is false, and the else block gets executed, and exitCode is changed to refer to good1. The next time through the loop, condition is set to refer to cond2 and exitCode is set to refer to 'very bad error'. Again, condition is refering to something, so the else block is executed and we do useful stuff again, which is probably not helpful and could well be harmful. exitCode is set to good1, we're finished with the loop, and we return exitCode. What happens if we try to do useful stuff, and we can't? Where does the error indication get set? And once it does get set, the only way we can exit the for loop is for condition to not refer to anything. How can that happen? Thank you very much for your explanation and your patience with one who only uses Python in very simplistic ways. RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: If/then style question
My thanks for pointing out the existence of the else: suite in the for statement. However, I remain confused. For reference, here's the original code: def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode What do we know about cond1 and cond2? Do they have to be assigned before this for statement is executed? The sample code doesn't show it. The loop is going to to execute once for condition = cond1 and exitCode = 'error1'. The only thing it's going to do is check to see what condition is. Since we can assume (I hope) that cond1 is not false, then the for loop continues. Now condition = cond2 and exitCode = 'very bad error'. The if condition is still false, so the loop continues. We've come to the end now, and the else: suite is executed. We finally do some useful stuff and exitCode = good1. (Should that have been in quotes, or doesn't it matter?) But now the for loop's job is done and we return the exitCode, which at this point is good1. But I still don't understand what happens if we can't do useful stuff. Where does an error code get set, and where is that error code checked? We don't have a chance to check it in the for loop, because once we're in the else: suite the loop condition is never rechecked. Or is it? Thanks again! RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: If/then style question
-Original Message- You have outlined what happens when cond1 and cond2 both evaluate to True -- what happens if, say, cond2 evaluates to False? - I reply And the light goes on! (And palm strikes forehead.) I was thinking that the error we were processing was raised by the do_some_useful_stuff() function. But the whole purpose of this thread was to evaluate error conditions that might have been set before we do useful stuff! Which, of course, was what the original poster was asking. My thanks again for your patience. RobR -- http://mail.python.org/mailman/listinfo/python-list
RE: Exception handling in Python 3.x
Arnaud, Wouldn't your first suggestion exit after the first element in iterable? And would your second suggestion throw an exception after normal processing of all elements in the interator? RobR -Original Message- I missed the start of this discussion but there are two simpler ways: def func(iterable): for x in iterable: print(x) return raise ValueError(... empty iterable) Or using 3.x's next's optional second argument: _nonext=object() def func(iterable): x = next(iter(iterable), _nonext) if x is _nonext: raise ValueError(... empty iterable) print(x) -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list