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 (vendor
, platform
, and 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: