Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does self[identifier] = some_value do in this code?

Tags:

python

I was just trying to learn K-ary tree implementation in Python and came across this link: http://www.quesucede.com/page/show/id/python-3-tree-implementation

In the tree.py file, there is a section of code like this:

class Tree:

    def __init__(self):
        self.__nodes = {}

    @property
    def nodes(self):
        return self.__nodes

    def add_node(self, identifier, parent=None):
        node = Node(identifier)
        self[identifier] = node

        if parent is not None:
            self[parent].add_child(identifier)

        return node

    # ... ...

    def __getitem__(self, key):
        return self.__nodes[key]

    def __setitem__(self, key, item):
        self.__nodes[key] = item

What is self[identifier]? Is it a list? This is really confusing. Can someone explain and/or point me to some documentation of using self as a list?

like image 268
Rahul Sarma Avatar asked Aug 03 '16 19:08

Rahul Sarma


2 Answers

In the full example code, this is the important bit:

def __getitem__(self, key):
    return self.__nodes[key]

def __setitem__(self, key, item):
    self.__nodes[key] = item

These two 'magic methods', __getitem__ and __setitem__, allow the class to be accessed like a list or dictionary would be, using the foo[key] syntax.

So, in your case, if foo was a Tree instance, foo["a"] = "b" would execute __setitem__ with key as "a" and item as "b", consequently mapping key to item in the self.__nodes dictionary.

like image 82
Aaron Christiansen Avatar answered Nov 01 '22 20:11

Aaron Christiansen


They are using the __getitem__ magic method. This method is used in a class to allow its instances to use [] (indexer) operators for list indexing, dictionary lookups, or accessing ranges of values.

In the fallowing sample, we have a list with some extra functionality like head and tail. Example taken from here:

class FunctionalList:
    '''A class wrapping a list with some extra functional magic, like head,
    tail, init, last, drop, and take.'''

    def __init__(self, values=None):
        if values is None:
            self.values = []
        else:
            self.values = values

    def __len__(self):
        return len(self.values)

    def __getitem__(self, key):
        # if key is of invalid type or value, the list values will raise the error
        return self.values[key]

    def __setitem__(self, key, value):
        self.values[key] = value

    def __delitem__(self, key):
        del self.values[key]

    def __iter__(self):
        return iter(self.values)

    def __reversed__(self):
        return FunctionalList(reversed(self.values))

    def append(self, value):
        self.values.append(value)
    def head(self):
        # get the first element
        return self.values[0]
    def tail(self):
        # get all elements after the first
        return self.values[1:]
    def init(self):
        # get elements up to the last
        return self.values[:-1]
    def last(self):
        # get last element
        return self.values[-1]
    def drop(self, n):
        # get all elements except first n
        return self.values[n:]
    def take(self, n):
        # get first n elements
        return self.values[:n]
like image 27
Jose Raul Barreras Avatar answered Nov 01 '22 22:11

Jose Raul Barreras