Python: Astar algorithm implementation
self.start, self.grid, self.height, self.width = start, grid, height, width

I would not put these all on the same line like that. I think it would be much easier to read spread over multiple lines:
self.start = start
self.grid = grid
self.height = height
self.width = width


I would probably have the Node class as toplevel instead of nested. I don't think you're gaining much by having it inside AStar. You could name it _Node to make it &quot;module-private&quot; so that attempting to import it to another file will potentially raise warnings.
In Node's __lt__ implementation, I wouldn't call the second parameter comparator. A comparator is something that compares, whereas in this case, that's just another node. other_node or something would be more appropriate.

In heuristic, I'd personally make use of an else there:
if (distance == &quot;Manhattan&quot;):
    return abs((x1 - x2) + abs(y1 - y2))
else:
    return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)

It makes it clearer that only one of the lines will be executed. Personally, I only neglect the else in a case like that if the if was an &quot;early exit&quot; precondition check, and I want to avoid nesting the entire rest of the function inside a block. That's not a problem here though.

nodeNeighbors (which should be node_neighbors) would be cleaner broken over several lines:
def nodeNeighbours(self, pos):
    (x, y) = pos
    return [(dx, dy)
            for (dx, dy) in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
            if 0 &lt;= dx &lt; self.width and 0 &lt;= dy &lt; self.height and self.grid[dy][dx] == 0]

I think that makes it a lot easier to see what's going on in it.

Again, in many places you're assigning two or more variables on one line:
(x1, y1), (x2, y2) = self.start, end
current, path = endPoint, []
openList, closedList, nodeDict = [], [], {}
x1, y1, y2, x2 = coordinates[0], coordinates[1], coordinates[2], coordinates[3]

I would break those up. Especially once you get to 3+ on a line, for the reader to see what variable matches up with what value, they'll need to count from the left instead of just checking what's on each side of a =.

In computePath, it seems like  closedList should be a set. It doesn't appear as though order matters with it, and neighbour in closedList will be faster with a set than it will with a list. It looks though like openList is required to be a list though due to it being passed to heapify.

I don't think I'd reassign stdin and stdout. The reassignment of stdin seems completely unnecessary, and changing stdout will make it harder to debug later using print statements. You don't necessarily want all printed text to be sent to the file.
If need-be, you can specify what file you want printed to when printing:
with open('output.txt', 'w') as out_f:
    print(&quot;To file!&quot;, file=out_f)