Today I want to share with you a small tip on how to dynamically set class attributes within Python. Before we do, I just want to point out that this is actually something I learnt a few months back after going through the Nornir code base. Therefore true kudos goes out to the Nornir devs! Also if you get a chance, I highly recommend checking out the Nornir code base as it acts as a great learning resource.
Great, so let's dive in...
So let's take a typical example where we statically assign our class attributes. Like so:
class Router: def __init__(self, vendor, platform, dc): self.vendor = vendor self.platform = platform self.dc = dc
We can then, of course, create an instance of
Router and then access the various attributes (
dc), like so.
>>> rtr001 = Router(vendor="Juniper", platform="junos", dc="London") >>> rtr001.vendor >>> 'Juniper' >>> rtr001.platform >>> 'junos' >>> rtr001.dc >>> 'London'
This is ok, but what about if we have a number of attributes we need to assign within our constructer (
__init__) or what if we want to provide an easy way to extend our
Router class in the future without the need of having to adapt the
__init__ each time.
This is where we can dynamically assign our instance attributes like so.
class Router: def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v)
Ok, so what is actually going on here? Let's go through this line by line:
class Router: # Pack all the keyword arguments provided at the point of creating # an instance of the class. These keyword args will then be available # via the kwargs dict(). def __init__(self, **kwargs): # We loop through each of the items in the dictionary and assign # the key to the variable 'k', and the value to the variable 'v'. for k, v in kwargs.items(): # We next assign an attribute to our instance/object using setattr. # The syntax is 'setattr(object, name, value)'. setattr(self, k, v)
Then as like before we can access our attributes, like so:
>>> rtr002 = Router(vendor="Cisco", platform="ios-xe", dc="Paris") >>> rtr002.vendor >>> 'Cisco' >>> rtr002.platform >>> 'ios-xe' >>> rtr002.dc >>> 'Paris'
Good stuff! Well, I hope you found this short Python tip useful. If you want to learn more about automating your network with Python, check our 5-day Bootcamp over at: