I am trying to write a function that will print the values of a object but only those values that are defined in a list.
import boto.ec2.cloudwatch
conn = boto.ec2.cloudwatch.connect_to_region('ap-southeast-1')
alarms = conn.describe_alarms()
for alarm in alarms:
print alarm.name
this will return a particular value for all alarms. How ever I want to make it work in such a way that I am able to print all the values that are defined in a list. Here is what I am trying to do
import boto.ec2.cloudwatch
conn = boto.ec2.cloudwatch.connect_to_region('ap-southeast-1')
alarms = conn.describe_alarms()
whitelist = ["name", "metric", "namespace"]
for alarm in alarms:
print alarm.whitelist[0]
However this wont works of course. Any suggestion about what will be the best way to do that? SO that I am able to print everything that is defined in a whitelist.
You can use getattr (note that you are referring to attributes, or possibly methods, not functions):
for alarm in alarms:
for attr in whitelist:
print getattr(alarm, attr)
getattr takes an optional third argument, the default value in case attr isn't found, so you could do e.g.:
for attr in whitelist:
print "{0}: {1}".format(attr, getattr(alarm, attr, "<Not defined>"))
You can use the getattr() built-in function.
Your code would looks something like this:
import boto.ec2.cloudwatch
conn = boto.ec2.cloudwatch.connect_to_region('ap-southeast-1')
alarms = conn.describe_alarms()
whitelist = ["name", "metric", "namespace"]
for alarm in alarms:
for attribute in whitelist:
print(getattr(alarm, attribute))
Related
I am trying to print a string, call functions and variables in a line.
such as [Hello! %(job), %(name)s, (function_name)]->[Hello! student, John, This is the function.]
json01.json
{
"test" : "Hello! %(job), %(name)s, (function_name)"
}
test01.py
import json
a = 'test'
name = 'John'
job = 'student'
def function_name(message):
print(message)
with open('json01.json') as json_file:
json_dict = json.load(json_file)
if a in json_dict:
print(json_dict[a] %locals())
#This works if there's only variables in the value
#but I don't know how to call functions when the value is not only function's name but also variables..
Is there any simple way to print whatever they are in the value?
or is there another way to do this work?
Sorry for the poor explanation and Thank you!
You can define your own function replacer using regular expressions. I defined an example syntax here as: Hello, !(function_name) where function_name is the name of the function that is called.
Using regular expressions we find all occurences of a function call and try to
evaluate them one by one. If successfull, we replace the function's name with the return value.
import re
def runfunctions(string):
# find all functions defined with our syntax
funcs = re.findall(r'!\((.*?)\)', string)
result = string
# iterate through found functions
for func in funcs:
try:
# try to evaluate with globals()[func]() and replace function call
# with return value
result = re.sub(r'!\(' + func + r'\)', globals()[func](), result)
except (KeyError, TypeError) as e:
# if func is not callable or does not exist catch error
print("Error while evaluating functions in string:", e)
# return final result
return result
Note: I used globals instead of locals as otherwise the function is not found.
You can use it like this:
if a in json_dict:
replaced_vars = json_dict[a] % locals()
replaced_funcs = runfunctions(replaced_vars)
print(replaced_funcs)
I have a number of constants,variable in which i keep names.
ATTR_ITEM_NAME = 'pro'
I check if the attribute is attached to an objects:
if hasattr(obj1, ATTR_ITEM_NAME):
then if exist I want the attribute value to be passed to an attribute of an object, something like this:
obj2.fm = obj1.ATTR_ITEM_NAME
ATTR_ITEM_NAME being a string and not an attribute is an error, I need something that works;
Python also has getattr which works like hasattr but returns the value:
obj2.fm = getattr(obj1, ATTR_ITEM_NAME)
If you are not sure the attribute exists you could:
assign a default value (e.g. None)
DEFAULT = None
obj2.fm = getattr(obj1, ATTR_ITEM_NAME, DEFAULT)
or catch the exception using
try:
obj2.fm = getattr(obj1, ATTR_ITEM_NAME)
except AttributeError:
pass # or do something else...
I'm working with a code that have this appearence:
module.py:
def attribute3():
return "something3"
def attribute2():
return "something2"
def attribute1():
return "something1"
main.py:
from module import attribute1, attribute2, attribute3
def main():
return {
"attribute1": attribute1(),
"attribute2": attribute2(),
"attribute3": attribute3()
}
print main()
And i would like to know if there is any better way to create the dictionary in the main function, without the necessaty of doing "attribute: function()". I'm feeling like i'm repeating my self.
I don't have access to the module.py code, so i can't change to a Class.
I'm using Python 2.5 because this is a legacy software.
Thanks.
You could use getattr and call the arbitrary functions returned.
import some_module
def create_dict(module, names):
resp = {}
for name in names: # Iterate over an arbitrary number of arguments
# Get the function with the name provided and call it,
# setting the response as the value for the name
resp[name] = getattr(module, name)()
return resp
print create_dict(some_module, ['attribute1', 'attribute2', 'attribute3'])
I didn't test this on Python 2.5 but I don't see any reason why it wouldn't work.
Let's say a have Person instance person. person may have an attribute id.
I want to write a function that gets me either an empty list [] when the attribute is None or missing or the list [12, ] when the attribute id is 12.
def get_id_list(person):
try:
return [getattr(person, 'id'), ]
except AttributeError:
return []
This works perfectly but is there a "pythonic" way of doing this without the try-except block and maybe in one line?
I would go for
def get_id_list(person):
_id = getattr(person, 'id', None)
return [] if _id is None else [_id]
However, it is good practice to make sure that attributes are always defined so you don't have to use getattr with a default or use hasattr to check for existence.
You may use hasattr() to check for attribute as:
def get_id_list(person):
if hasattr(person, 'id'):
return [person.id] # better then getattr(person, 'id')
else:
return []
which could be written in one line as:
def get_id_list(person):
return [person.id] if hasattr(person, 'id') else []
There are two basic ways of going about this:
EAFP (It's Easier to Ask Forgiveness than Permission)- which is what you have:
def get_id_list(person):
try:
return [person.id]
except AttributeError:
return []
LBYL (Look Before You Leap)
def get_id_list(person):
if hasattr(person, 'id'):
return [person.id]
else:
return []
Generally, EAFP is "pythonic", but really, it depends on the specifics of your use-case. If you know that person will usually have the id attribute, then you should use EAFP. That is to say, if it is an exceptional case for person not to have id, use exceptions! If, on the other hand, it is common for person to lack id, then LBYL will be more efficient.
If you simply want a one-liner, you could use a conditional expression:
return [person.id] if hasattr(person,'id') else []
Your approach is pythonic, just do some few tweaking.
First off, don't return inside the try block. You can preserve the id value in a variable and return it properly within else clause. The reason is that you are doing multiple operation like getting attribute and converting to list (and maybe more(in other cases)) while you are just catching the AttributeError. And when you use else you can handle other exceptions easily, also it's more elegant from coding style's perspective.
Secondly you don't need to use getattr in this case, you can simply use direct attribute access.
Also instead of using the try-except you might want to check if the object has the attribute then return its value but due to It's easier to ask forgiveness than it is to get permission. principal the try-exepct is better.
def get_id_list(person):
try:
id = person.id
except AttributeError:
return []
else:
return [id]
getattr() allows you to specify a default if the attribute isn't there so you could use that if you want to avoid a try/catch block.
If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.
id = getattr(person, 'id', None)
if id is not None:
return [id]
return []
You can provide a default value (a third argument) to getattr() function to be returned if an attribute does not exist:
def get_id_list(person):
id_ = getattr(person, 'id', None)
return [id_] if id_ is not None else []
(assuming here that None is not a valid value for the id attribute)
according to the Python documentation:
EAFP:
Easier to ask for forgiveness than permission. This common Python
coding style assumes the existence of valid keys or attributes and
catches exceptions if the assumption proves false. This clean and fast
style is characterized by the presence of many try and except
statements. The technique contrasts with the LBYL style common to many
other languages such as C.
That means that your code follows the "official" pythonic way, checking if the attribute exists would be less pythonic.
However, performance needs could eventually override pythonic consideration according to the frequence where person object will not have an id attribute, because raising an exception takes more time than evaluating a simple condition.
Consider following code:
import os
from timeit import timeit
def get_id_list_try(person):
try:
return [person.id]
except AttributeError:
return []
def get_id_list_if(person):
if hasattr(person, 'id'):
return [person.id]
else:
return []
class Person(object):
def __init__(self, id):
self.id = id
person_with_id = Person(1664)
person_no_id = object()
print("try with id: {}".format(
timeit("get_id_list_try(person_with_id)", number=1000000,
setup="from __main__ import get_id_list_try, person_with_id")))
print("try no id: {}".format(
timeit("get_id_list_try(person_no_id)", number=1000000,
setup="from __main__ import get_id_list_try, person_no_id")))
print("if with id: {}".format(
timeit("get_id_list_if(person_with_id)", number=1000000,
setup="from __main__ import get_id_list_if, person_with_id")))
print("if no id: {}".format(
timeit("get_id_list_if(person_no_id)", number=1000000,
setup="from __main__ import get_id_list_if, person_no_id")))
It tests the performance of the try/catch and the if/else methods with and without an id. It prints this:
try with id: 0.25232274121
try no id: 2.32747888986
if with id: 0.364873724104
if no id: 0.728008592266
As you can see, the try/catch method is a bit faster when an id exists; but when the id does not exists the if/else method is 3 times faster than try/catch method.
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?
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
Do not use setattr. Just assign a value to the "last" key for each machine dictionary.
(actually you answered your own question!)
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 :-)