In Python, I am populating an object to model the configuration, environment and other aspects related to rsyslog on the local machine (RHEL 6.4 Python 2.6.4) I loop through many instances of the rsyslog daemon (this_instance_number), and many attributes (attribute) defined in a configuration file.
With those value I populate the object.
Given the following variables:
this_instance_number=5
attribute="startupscript"
The following line of code,
print ('rsyslog.instance%(instance_number)s.%(attribute)s' %\
{"instance_number": this_instance_number, "attribute": attribute})
will print this text:
rsyslog.instance5.startupscript
How can I then assign the attribute that text would refer to to a value based on that format string?
For example, if hard coded, I would assign:
rsyslog.instance5.startupscript="/etc/init.d/sample"
But, I want to assign it something like this:
('rsyslog.instance%(instance_number)s.%(attribute)s' %\
{"instance_number": this_instance_number, "attribute": attribute}) = variable
You'd use getattr() to dynamically retrieve attributes:
instance = getattr(rsyslog, 'instance{}'.format(this_instance_number))
print getattr(instance, attribute)
and setattr() to assign:
instance = getattr(rsyslog, 'instance{}'.format(this_instance_number))
setattr(instance, attribute, variable)
or, for a more generic approach with arbitrary depth:
def get_deep_attr(obj, *path):
return reduce(getattr, path, obj)
def set_deep_attr(obj, value, *path)
setattr(get_deep_attr(obj, path[:-1]), path[-1], value)
print get_deep_attr(rsyslog, 'instance{}'.format(this_instance_number), attribute)
set_deep_attr(rsyslog, variable, 'instance{}'.format(this_instance_number), attribute)
Related
Currently I am working on a selenium project which I am integrated with Jenkins.I have stored Locators in a class. So my target is to take input from jenkins and use that variable as a key to get value from the
class Locators(object):
rundate = 'PREV' # This value is user input, either PREV or NOW
PREV = 'abcd'
NOW = 'bcd'
So I want to use it as:
Test = Locators()
Test.(Test.rundate)
Dotted attribute access always requires a valid identifier for the attribute name, not an arbitrary expression. Use getattr in other situations.
getattr(Test, Test.rundate)
I struggle with using variables (ultimately dictionary) for dynamically compose and access class attributes using getattr:
from gpiozero import PiStop
lights = PiStop('A+')
# working call: lights.red.on()
var = 'red.on'
getattr(lights(), var) # doesn't work - error
I cannot find proper syntax...
You have two attributes being accessed; lights.red is one such attribute, and on the result of that access, you then apply another attribute access, so <result>.on.
You need to use separate getattr() calls to achieve the same.
You could split on the '.' dot in var and apply each name separately, in a loop:
result = lights()
for name in var.split('.'):
result = getattr(result, name)
This allows for var to be set to any number of nested attributes.
Goal: get "Python names" of attributes from an instance of Example, where the model was defined with a different datastore name
To provide some context, I have a custom to_dict() method for serializing an NDB Model. The core of the method is as follows:
for key, prop in self._properties.iteritems():
if hasattr(self, key):
value = getattr(self,key)
# do typical to_dict() stuff
If a model is defined as follows, everything is fine:
import Thing
class Example(ndb.Model):
things = ndb.KeyProperty(Thing, repeated=True)
However, there are issues if it defined where the the Python name is things but the datastore name is 'Thing':
# no import req'd
class Example(ndb.Model):
things = ndb.KeyProperty('Thing', repeated=True)
In the first scenario, the key from self._properties.iteritems() would be things. If I have an instance of Example, say example, then hasattr(example,'things') would evaluate to True.
In the second scenario, the key would be Thing and hasattr(example,'Thing') would evaluate to False, since the instance of Example has attributes defined by the Python name 'things'.
How can I get the properties of the instance? TIA.
ndb's own Model._to_dict method does it as follows (simplifying):
for prop in self._properties.itervalues():
name = prop._code_name
values[name] = prop._get_for_dict(self)
So: the name is taken from the _code_name of each property (not its key in self._properties, and the value is delegated to the property itself (via its _get_for_dict method) to allow further tweaking.
As a result, coding both of your examples as Example1 and Example2, whole their _properties.items() are respectively:
[('things', KeyProperty('things', repeated=True, kind='Thing'))]
[('Thing', KeyProperty('Thing', repeated=True))]
their ._to_dict(), as desired, both equal
{'things': [Key('Thing', 'roro')]}
I have a Python class , having some variables. The definition of the class is as follows:
class student:
def __init__(self,name,rollno,DOB,branch):
self.name=name
self.rollno=rollno
self.DOB=DOB
self.branch=branch
self.books=[]
self.fines=[]
I am adding new attributes for a student , and need to store the corresponding values as well (for future use). This is done using the setattr method, and works fine.
Code snippet:
setattr(student,"date_of_join",date())
Now I am approaching the problem as, if the user adds a new attribute (say, "date_of_join"), then I update a list (studattr), initially containing ["name","rollno",DOB","branch","books","fines"] to update the list of attributes. This means that the updated list will also have "date_of_join" now appended to it.
Now if I want to access this list of attributes of a student Instance, then how do I do it? ( Since the records are dynamically updated, and let us suppose I have to access x.date_of_join, then how do I join the two strings? Is there anything similar to python's os.path.join, or rather linux's system call, (merging two strings)? )
Problem:
for attribute in studattr:
print attribute,x.attribute
{ This throws an Exception since the instance x has no variable or method named "attribute")
PS: I tried using inspect,inspect.getmembers(x) as well as dirs(x), vars(x) ,(mentioned on stackoverflow), but it only gives me a list of variables/methods in main class body and not in init.
Use getattr() to access dynamic attributes:
for attr in student.studattr:
print attr, getattr(student, attr)
or use vars() will give you a dictionary of current attributes on a student:
for attr, value in vars(student).iteritems():
print attr, value
I've looked at documentation, and have searched Google extensively, and haven't found a solution to my problem.
This is my readRSS function (note that 'get' is a method of Kenneth Reitz's requests module):
def readRSS(name, loc):
linkList = []
linkTitles = list(ElementTree.fromstring(get(loc).content).iter('title'))
linkLocs = list(ElementTree.fromstring(get(loc).content).iter('link'))
for title, loc in zip(linkTitles, linkLocs):
linkList.append((title.text, loc.text))
return {name: linkList}
This is one of my MongoAlchemy classes:
class Feed(db.Document):
feedname = db.StringField(max_length=80)
location = db.StringField(max_length=240)
lastupdated = datetime.utcnow()
def __dict__(self):
return readRSS(self.feedname, self.location)
As you can see, I had to call the readRSS function within a function of the class, so I could pass self, because it's dependent on the fields feedname and location.
I want to know if there's a different way of doing this, so I can save the readRSS return value to a field in the Feed document. I've tried assigning the readRSS function's return value to a variable within the function __dict__ -- that didn't work either.
I have the functionality working in my app, but I want to save the results to the Document to lessen the load on the server (the one I am getting my RSS feed from).
Is there a way of doing what I intend to do or am I going about this all wrong?
I found out the answer. I needed to make use of a computed_field decorator, where the first argument was the structure of my return value and deps was a set which contained the fields that this field was dependent on. I then passed the dependent fields into a function's arguments and there you have it.
#fields.computed_field(db.KVField(db.StringField(), db.ListField(db.TupleField(db.StringField()))), deps=[feedname, location])
def getFeedContent(a=[feedname, location]):
return readRSS(a['feedname'], a['location'])
Thanks anyway, everyone.