1

I'm making my first attempts at Python.

I need to loop over a log, parse log entries and then update an object, which includes nested objects for machines listed in the log.

This is what I have:

import re
format_pat= re.compile( 
    r"(?P<host>(?:[\d\.]|[\da-fA-F:])+)\s" 
    r"(?P<identity>\S*)\s" 
    r"(?P<user>\S*)\s"
    r"\[(?P<time>.*?)\]\s"
    r'"(?P<request>.*?)"\s'
    r"(?P<status>\d+)\s"
    r"(?P<bytes>\S*)\s"
    r'"(?P<referer>.*?)"\s'
    r'"(?P<user_agent>.*?)"\s*' 
)

from json import JSONEncoder
class MyEncoder(JSONEncoder):
    def default(self, o):
      return o.__dict__ 

# JSON response object
class ResponseObject(object):
    def __init__(self, dict):
      self.__dict__ = dict


# check for JSON response object
try:
    obj
except NameError:
    obj = ResponseObject({})

test = ['2001:470:1f14:169:15f3:824f:8a61:7b59 - SOFTINST [14/Nov/2012:09:32:31 +0100] "POST /setComputer HTTP/1.1" 200 4 "-" "-" 102356']

# log loop
for line in test:
  try:
    # try to create object from log entry
    m = format_pat.match(line)
    if m:
      res = m.groupdict()
      res["status"] = int(res["status"])

      # register machine if not done
      if not hasattr(obj, res["user"]):
        setattr(obj, res["user"], {"downtime":"0","flag":"false","downstart":"0","init":res["time"],"last":"","uptime":"","downtime":"","totaltime":""})


      machine = getattr(obj, res["user"])
      flag = machine["flag"]
      start = machine["downstart"]
      down = machine["downtime"]
      last = machine["last"]

      print "done"
      # set last
      last = res["time"]

      # PROBLEM this does not work
      setattr(machine, last, res["time"])
      print machine

    else:
      print "nope"
  except:
      print "nope base"

print MyEncoder().encode(obj)

The error I'm getting when trying to setattr() is

AttributeError: 'dict' object has no attribute ''

but I was afraid it was not as easy as this...

Question:
How do I update the last value in my nested object using 'setattr'? Or is there another way to update nested object attributes?

2
  • "...but I was afraid it was not as easy as this..."? It's actually easier than you were thinking. Sounds like it would help to familiarize yourself with Python data structures such as the dictionary. Commented Mar 5, 2013 at 17:48
  • well... true. First day with Python :-) Commented Mar 5, 2013 at 19:06

3 Answers 3

1

I think you need to do this:

setattr(machine, 'last', res["time"])

As setattr needs a string of the name of the attribute to be set

Sign up to request clarification or add additional context in comments.

5 Comments

doesn't seem to work. Also I can use setattr further up in the code with a res["user"]
@frequeent But what do you want? You want machine to have an attribute named last, or you want it to have an attribute which name is inside the variable last?
machine should have an attribute last with the time of the log entry
@frequent Ok then you need to do exactly what is in my answer, what error are you getting?
it's still the same error ’AttributeError: 'dict' object has no attribute 'last'’. Your answer makes sense though. I don't understand why it's not working.
1

Do not use setattr. Just assign a value to the "last" key for each machine dictionary.

(actually you answered your own question!)

Comments

0

I don't understand why, but I can set the value of last like this:

  print machine
  print machine["last"]
  print res["time"]

  # this works
  machine["last"] = res["time"]

  print machine

If someone can explain, would be nice :-)

1 Comment

machine is a dict. That's why you can set the value of "last" key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.