以下是3个模块,
point.py
segment.py
rectangle.py
,
其中rectangle.py
模块从segment.py
模块导入一个函数对象,如上所述,
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)
我的问题:
根据rectangle.py
的调试,
行from segment import get_size
使segment.py
的驱动程序代码执行并输出(2.0, 3.0)
。
我正在使用此声明来访问get_size
。我想了解,函数对象的导入如何给出这个输出?
答案 0 :(得分:2)
在python中导入模块基本上意味着您将它们作为脚本执行。即使您说import foo
或from foo import bar
,这种情况也会发生。 Python需要运行foo
才能找到函数bar
。
在第一种情况下(import foo
),您可以访问完整的命名空间,即您可以使用foo.getsize()
或foo.bar()
或您的模块提供的任何函数,对象或其他内容。而在后一种情况下(from foo import bar
),您只将函数bar
导入当前命名空间,例如,您只能使用bar()
,而不能使用getsize()
。
此外,有一种简单的方法可以让python执行模块的各个部分,当且仅当它作为主模块运行时,不是(如果它被导入)。例如,在segment.py
中,您可以在脚本末尾写下以下内容:
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()
首先,我们定义一个main
函数。如果语句main
为__name__ == '__main__'
,则此True
函数仅 。这是什么意思?好吧,__name__
是模块本身的固有变量。每次通过python segment.py
运行模块或通过import segment
或from segment import something
导入模块时,此变量的设置都不同。
如果您通过python segment.py
运行模块,则__name__
等于字符串'__main__'
。如果您导入模块,__name__
将设置为模块的名称,此处为'segment'
。因此,您可以轻松区分模块是作为主文件运行还是仅由其他文件导入。
编辑:
有关为什么from foo import bar
需要完全执行foo
的更多信息!?
如果Python没有执行foo
,那么Python应该如何知道该模块包含函数bar
? Python是一种解释型语言,因此函数和其他对象实际上只是在运行时从源代码创建的。
然而,Python非常聪明,只能一次执行您的脚本。因此,其他几个foo
导入 - 即使在其他脚本中 - 也不需要重新执行您的模块,因为 foo 的命名空间已经建立。此行为在允许您在运行时自由修改任何模块/包(也来自其他人)方面具有一些优势。因此,如果你知道自己在做什么,你可以修补任何导入模块的功能和对象。这些修改可能会影响程序的整个范围(包括导入已修改库的所有其他模块和脚本)。
请注意,这通常是危险的,但有时会非常有帮助。
无论如何,THIS也可能是有用的阅读。
/ EDIT
答案 1 :(得分:0)
通过执行from something import somethingelse
,您仍然导入something
,然后只需将somethingelse
添加到您的命名空间,以便something
模块得到处理,这意味着您的顶级代码将会运行你是从打印
如果您不希望不具备任何不属于类或函数声明的模块级代码