Coding trick: Setattr vs. Exec

Recently, while writing a parser for files, in Python, I needed to dynamically assign variables. As an aide memoire for me and maybe for the rest of the world this post will talk about the trick.

code_snippet from Komodo IDE

So what is the code doing?

reg_01 = re.compile(r'.*core.xml')

Here we are compiling a Regex to match something ending ‘core.xml’.

if filter(reg_01.match,self.plist):

We are searching a list of pseudo files (from an archive) using the filter function.

The filter resembles a for loop but it is a builtin function and faster.

for item in filter(reg_01.match,self.plist):
parsed = XML(extract_file(self.pf,item))

This extracts the file from the archive and parses it as an XML file.

for elem in parsed:
taggy = re.sub(r'{[^}]*}','',elem.tag)

The XML tag has extraneous information that the Regular Expression substitution removes.

Before we go any further let us look at an example core.xml file.

<dc:title>This is the title</dc:title>
<dc:creator>God</dc:creator>
<cp:lastModifiedBy>Woman</cp:lastModifiedBy>
<cp:revision>2</cp:revision>
<dcterms:created xsi:type="dcterms:W3CDTF">1970-01-01T00:00:00Z</dcterms:created>

So what I would like to be displayed is:

  • self.title = ‘This is the title’
  • self.creator = ‘God’
  • self.lastModifiedBy = ‘Woman’
  • self.revision = ‘2’
  • self.created = ‘1970-01-01T00:00:00Z’

The first way of getting this result I found was:

#exec('self.' + taggy +' = ' + 'elem.text')

The use of the exec is frowned upon. When I came to rewrite the code (for another similar parser) I found setattr.

setattr(self, taggy, elem.text)

This code using setattr is much cleaner and simpler. Python unlike Perl strives that: “There should be one– and preferably only one –obvious way to do it.” see PEP 20.

Advertisements

Book Review: Python Crash Course

Book Cover

Python Crash Course:
A Hands-On, Project-Based Introduction To Programming

by Eric Matthes

no starch press
ISBN: 978-1-59327-603-4

no starch press is rapidly becoming one of my favourite tech publishers. This book is quiet long but there isn’t much fat to trim. To find ~500 pages of useful technical information is a very difficult thing to do and yet Eric and his editors have managed it.

This book is based on Python 3 but explains where Python 2.7 differs. The book is divided in to two parts:

  • Part I: Basics
  • Part II: Projects
    • Project I: Alien Invasion
    • Project II: Data Visualisation
    • Project III: Web Applications

Full Disclosure I have only read Part I and have skimmed Part II for this review. When I have time I will go through the second part and write the code.

In each topic the author starts small and slowly builds on that part to show how to build better code. From:

def greet_user():
"""Displaying a simple greeting."""
print("Hello!")

greet_user()

to:

def greet_user(username):
"""Displaying a simple greeting."""
print("Hello," + username.title() + "!")

greet_user(‘jesse’)

explaining each line as you go. The explanations are really clear and it is now my goto resource for explaining things when Stack Overflow is not clear.

Last week, I wrote my first Python class and though I have been playing with Python for a few years I had never understood when and where to use a class. Over the next few weeks I expect I will be referencing the book more as I will be building more programs in Python.

I would recommend this book if:

    • like me, you have had no formal training in Python or,
    • like me, you have not encountered Python 3 before
    • you have to do implement any of the projects!

Though the highest recommendation is that I will be lending it to my nephew as he has been doing some Python courses at University and this book would make a great addition for any science student because the future of much science is Data Analysis and Python is a great (free) tool for that.