Below are 3 modules,

`point.py` `segment.py` `rectangle.py`,

where `rectangle.py` module imports a function object from `segment.py` module as mentioned,

`from segment import get_size`.

``# point.py# Representation - startfrom operator import sub, mulfrom math import sqrt#Constructordef make_point(x, y):return (x, y)#Selectordef x_coordinate(point):return point[0]#Selectordef y_coordinate(point):return point[1]#Selectordef distance_between_points(p1, p2):return sqrt(square(sub(p1[0],p2[0])) + square(sub(p1[1],p2[1])))#helper for selectordef square(a):return mul(a, a)#Representation - end#Use - startdef get_x_coordinate(point):return x_coordinate(point)def get_y_coordinate(point):return y_coordinate(point)#Use - end``

``# segment.py# Representation - startfrom point import distance_between_points, make_point, get_x_coordinate, get_y_coordinate#Constructordef make_segment(point1, point2):return (point1, point2)#Selectordef start_segment(lineSegment):return lineSegment[0]#Selectordef end_segment(lineSegment):return lineSegment[1]#Representation - end#Use -startdef midpoint_segment(lineSegment):return make_point((get_x_coordinate(start_segment(lineSegment)) + get_x_coordinate(end_segment(lineSegment)))/2, (get_y_coordinate(start_segment(lineSegment)) + get_y_coordinate(end_segment(lineSegment)))/2)def get_size(lineSegment):return distance_between_points(start_segment(lineSegment), end_segment(lineSegment))#Use - end#Driver code from userp1 = make_point(1,2)p2 = make_point(3, 4)line = make_segment(p1, p2)midpoint = midpoint_segment(line)print(midpoint)``

``# rectangle.py# Representation - startfrom point import make_point, get_x_coordinate, get_y_coordinatefrom segment import get_sizefrom operator import sub, abs#Constructordef make_rectangle(p1, p2, p3, p4):if are_opposite_sides_equal(p1, p2, p3, p4):return (p1, p2, p3, p4)#Helper for constructordef are_opposite_sides_equal(p1, p2, p3, p4):if (abs(sub(get_x_coordinate(p1), get_x_coordinate(p2))) == abs(sub(get_x_coordinate(p3), get_x_coordinate(p4)))) and (abs(sub(get_y_coordinate(p2), get_y_coordinate(p3))) == abs(sub(get_y_coordinate(p1), get_y_coordinate(p4)))):return Trueelse:return False#Selectordef get_length_side_segment(quadruple):return (quadruple[0], quadruple[1])#Selectordef get_breadth_side_segment(quadruple):return (quadruple[1], quadruple[2])#Representation - end#Use -startdef perimeter(rectangle):segment1 = get_length_side_segment(rectangle)segment2 = get_breadth_side_segment(rectangle)length = get_size(segment1)breadth = get_size(segment2)return 2 * (length + breadth)def area(rectangle):segment1 = get_length_side_segment(rectangle)segment2 = get_breadth_side_segment(rectangle)length = get_size(segment1)breadth = get_size(segment2)return (length * breadth)#Use - end#Driver code from userp1 = make_point(1, 1)p2 = make_point(3, 1)p3 = make_point(3, 3)p4 = make_point(1, 3)rectangle = make_rectangle(p1, p2, p3, p4)peri = perimeter(rectangle)area_value = area(rectangle)print(peri)print(area_value)``

My question:

As per the debugging of `rectangle.py`,

line `from segment import get_size` makes the driver code of `segment.py` execute and give the output `(2.0, 3.0)`.

I am using this statement to get access to `get_size`. I would like to understand, How an import of function object would give this output?

Importing modules in python basically means you execute them as a script. This happens in both cases, even if you say `import foo` or `from foo import bar`. Python needs to run `foo` to be able to find the function `bar`.

In the first case (`import foo`) you have access to the full namespace, i.e. you could use `foo.getsize()` or `foo.bar()` or whatever functions, objects or whatnots your module provides. Whereas in the latter case (`from foo import bar`) you import only the function `bar` into your current namespace, i.e. you could only use `bar()`, but not `getsize()`, for example.

Furthermore, there is a simple way to make python execute parts of a module if and only if it is run as the main module and not if it is imported. For instance, in `segment.py`, you could write the following at the end of the script:

``````def main()
#Driver code from user
p1 = make_point(1,2)
p2 = make_point(3, 4)
line = make_segment(p1, p2)
midpoint = midpoint_segment(line)
print(midpoint)

if __name__ == '__main__':
main()
``````

First of all, we define a `main` function. This `main` function is only called if the statement `__name__ == '__main__'` is `True`. What does this mean? Well, `__name__` is an inherent variable of the module itself. Every time the module is run via `python segment.py` or imported via `import segment` or via `from segment import something`, this variable is set differently.

If you run the module via `python segment.py`, `__name__` is equal to the string `'__main__'`. If you import the module, `__name__` is set to the name of the module, here `'segment'`. Thus, you can easily distinguish if a module is run as a main file or just imported by another file.

EDIT:

More on why does `from foo import bar` needs to fully execute `foo`!?

If Python did not execute `foo`, how should Python know that the module contains the function `bar`? Python is an interpreted language, so functions and other objects are really only created from source during runtime.

However, Python is smart enough to execute your script only once. Thus, several other imports of `foo` - even in other scripts - do not require re-executing your module, because the namespace of foo is already established. This behaviour has some advantages in terms of giving you freedom to modify any module/package (also from other people) during runtime. So if you know what you are doing, you can monkey-patch functions and objects of any imported module. These modifications can affect the whole scope of your program (including all other modules and scripts importing the modified library). Note that this is often dangerous but from time to time incredibly helpful.

Anyhow, THIS might also be a useful read.

/EDIT.

by doing `from something import somethingelse` you still import `something` and then just add `somethingelse` to your namespace so the `something` module does get processed meaning your top level code will get run hence you are getting the output from print

if you don't want that don't have any module level code that is not a class or function declaration

Top