Q: Why use iter() to make a list an iterable? class Node:
    def __init__(self, value):
         self._value = value
         self._children = []
    def __repr__(self):
         return 'Node({!r})'.format(self._value)
    def add_child(self, node):
         self._children.append(node)
    def __iter__(self):
         return iter(self._children)
    def depth_first(self):
         yield self
         for c in self:
             yield from c.depth_first()
if __name__ == '__main__':
    root = Node(0)
    child1 = Node(1)
    child2 = Node(2)
    root.add_child(child1)
    root.add_child(child2)
    child1.add_child(Node(3))
    child1.add_child(Node(4))
    child2.add_child(Node(5))

for a in root.depth_first():
    print(a)
# Outputs Node(0), Node(1), Node(3), Node(4), Node(2), Node(5)

I thought that a list is an object that we can iterate over it so why use iter() ? I am new in python so this look to me so weird.

A: Because returning self._children returns a list object, which doesn't work as an iterator, remember, iterators implement the __next__ method in order to supply items during iteration:
>>> next(list())  # doesn't implement a __next__ method
TypeError: 'list' object is not an iterator

lists are iterable, they can be iterated through because calling iter on the will return an iterator, but, lists themselves are not iterators -- a good breakdown of these can be found in the top answer of this Question.
A lists __iter__ method returns a custom  new list_iterator object each time __iter__ is called: 
list().__iter__()
Out[93]: <list_iterator at 0x7efe7802d748>

and, by doing that, supports iteration multiple times, the list_iterator object implements the __next__ method that's required. 
Calling and returning iter on it will just do that, return the lists iterator and save you the trouble of having to implement __next__.

Addressing your comment as for why for c in self._children works, well, because it is essentially doing the same thing. What basically happens with the for loop is:
it = iter(self._children)  # returns the list iterator
while True:
    try:
        i = next(it)
        <loop body>
    except StopIteration:
        break

meaning, iter is called again on the list object and is used by the for loop for next calls.

A: Every iterable object implements an iter() function that returns itself.
the iter(obj) calls the obj.iter(), which is same as returning the list object in your example.
