I'm imitating the behavior of the ConfigParser
module to write a highly specialized parser that exploits some well-defined structure in the configuration files for a particular application I work with. The files follow the standard INI structure:
[SectionA]
key1=value1
key2=value2
[SectionB]
key3=value3
key4=value4
For my application, the sections are largely irrelevant; there is no overlap between keys from different sections and all the users only remember the key names, never which section they're supposed to go in. As such, I'd like to override __getattr__
and __setattr__
in the MyParser
class I'm creating to allow shortcuts like this:
config = MyParser('myfile.cfg')
config.key2 = 'foo'
The __setattr__
method would first try to find a section called key2
and set that to 'foo' if it exists. Assuming there's no such section, it would look inside each section for a key called key2
. If the key exists, then it gets set to the new value. If it doesn't exist, the parser would finally raise an AttributeError
.
I've built a test implementation of this, but the problem is that I also want a couple straight-up attributes exempt from this behavior. I want config.filename
to be a simple string containing the name of the original file and config.content
to be the dictionary that holds the dictionaries for each section.
Is there a clean way to set up the filename
and content
attributes in the constructor such that they will avoid being overlooked by my custom getters and setters? Will python look for attributes in the object's __dict__
before calling the custom __setattr__
?
Python's magic method __setattr__() implements the built-in setattr() function that takes an object and an attribute name as arguments and removes the attribute from the object. We call this a “Dunder Method” for “Double Underscore Method” (also called “magic method”).
Python setattr() Python setattr() function is used to assign a new value to the attribute of an object/instance. Setattr in python sets a new specified value argument to the specified attribute name of a class/function's defined object.
If the attribute is not found, setattr() creates a new attribute an assigns value to it. However, this is only possible if the object implements the __dict__() method. You can check all the attributes of an object by using the dir() function.
What is the use of the setattr() method in inheritance? The use case of setattr() in inheritance is the same, i.e., to assign value to the attributes of an object.
pass filename
, content
to super class to handle it
class MyParser(object):
def __setattr__(self, k, v):
if k in ['filename', 'content']:
super(MyParser, self).__setattr__(k, v)
else:
# mydict.update(mynewattr) # dict handles other attrs
I think it might be cleaner to present a dictionary-like interface for the contents of the file and leave attribute access for internal purposes. However, that's just my opinion.
To answer your question, __setattr__()
is called prior to checking in __dict__
, so you can implement it as something like this:
class MyParser(object):
specials = ("filename", "content")
def __setattr__(self, attr, value):
if attr in MyParser.specials:
self.__dict__[attr] = value
else:
# Implement your special behaviour here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With