当前位置: 动力学知识库 > 问答 > 编程问答 >

Importing function of a module in python

问题描述:

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 - start

from operator import sub, mul

from math import sqrt

#Constructor

def make_point(x, y):

return (x, y)

#Selector

def x_coordinate(point):

return point[0]

#Selector

def y_coordinate(point):

return point[1]

#Selector

def distance_between_points(p1, p2):

return sqrt(square(sub(p1[0],p2[0])) + square(sub(p1[1],p2[1])))

#helper for selector

def square(a):

return mul(a, a)

#Representation - end

#Use - start

def get_x_coordinate(point):

return x_coordinate(point)

def get_y_coordinate(point):

return y_coordinate(point)

#Use - end


# segment.py

# Representation - start

from point import distance_between_points, make_point, get_x_coordinate, get_y_coordinate

#Constructor

def make_segment(point1, point2):

return (point1, point2)

#Selector

def start_segment(lineSegment):

return lineSegment[0]

#Selector

def end_segment(lineSegment):

return lineSegment[1]

#Representation - end

#Use -start

def 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 user

p1 = make_point(1,2)

p2 = make_point(3, 4)

line = make_segment(p1, p2)

midpoint = midpoint_segment(line)

print(midpoint)


# rectangle.py

# Representation - start

from point import make_point, get_x_coordinate, get_y_coordinate

from segment import get_size

from operator import sub, abs

#Constructor

def make_rectangle(p1, p2, p3, p4):

if are_opposite_sides_equal(p1, p2, p3, p4):

return (p1, p2, p3, p4)

#Helper for constructor

def 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 True

else:

return False

#Selector

def get_length_side_segment(quadruple):

return (quadruple[0], quadruple[1])

#Selector

def get_breadth_side_segment(quadruple):

return (quadruple[1], quadruple[2])

#Representation - end

#Use -start

def 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 user

p1 = 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

分享给朋友:
您可能感兴趣的文章:
随机阅读: