I'm fairly new to Python. In programming a lot of PHP recently I got used to some creative use of __get
and __set
"magic" methods. These were only called when a public variable of the class wasn't present.
I'm trying to replicate the same behavior in Python, but seem to be failing miserably. Given there doesn't seem to be a way to actually define class variables in a C++/PHP way, when I try to use variables normally within my class (i.e. via self) it ends up calling __getattr__
!
How do I define attributes of my class that I don't want affected by __getattr__
?
Some sample code of what I'm trying to do is below, where I'd want self.Document
and self.Filename
NOT to invoke __getattr__
.
Thanks for the help!
class ApplicationSettings(object):
RootXml = '<?xml version="1.0"?><Settings></Settings>'
def __init__(self):
self.Document = XmlDocument()
self.Document.LoadXml(RootXml)
def Load(self, filename):
self.Filename = filename
self.Document.Load(filename)
def Save(self, **kwargs):
# Check if the filename property is present
if 'filename' in kwargs:
self.Filename = kwargs['filename']
self.Document.Save(self.Filename)
def __getattr__(self, attr):
return self.Document.Item['Settings'][attr].InnerText
def __setattr__(self, attr, value):
if attr in self.Document.Item['Settings']:
# If the setting is already in the XML tree then simply change its value
self.Document.Item['Settings'][attr].InnerText = value
else:
# Setting is not in the XML tree, create a new element and add it
element = self.Document.CreateElement(attr)
element.InnerText = value
self.Document.Item['Settings'].AppendChild(element)
Apparently if I check for the attribute name in __setattr__
I can then call object's __setattr__
for the attributes I want to use normally. This feels pretty hoaky, but works.
def __setattr__(self, attr, value):
# Check for attributes we want to store normally
if attr == 'Document' or attr == 'Filename':
object.__setattr__(self, attr, value)
# If the setting is already in the XML tree then simply change its value
elif attr in self.Document.Item['Settings']:
self.Document.Item['Settings'][attr].InnerText = value
# Setting is not in the XML tree, create a new element and add it
else:
element = self.Document.CreateElement(attr)
element.InnerText = value
self.Document.Item['Settings'].AppendChild(element)