我是python的菜鸟,我想了解import语句的工作原理。
我正在运行python 3.6。 我有空闲工作。
我的测试目录设置为
目录:test_py
在目录test_py中我有文件 test_calc.py,button.py,graphics.py
graphics.py是一个图形库。
我的主程序是 test_calc.py 。
在 test_calc.py 中,我使用 from graphics import * 。它的第一行
button.py是一个包含类定义Button的模块。 它还使用图形库graphics.py。
test_calc.py中的主程序使用Button类。 Button类定义还调用Point,这是图形库中的一个函数。
我认为创建Button对象的调用将能够使用graphcs 来自test_calc.py中语句来自图形导入* 的库,但它不能。
button.py还需要 from graphics import * 来访问图形库函数。
我有没有办法在test_calc.py中使用图形导入* **中的** 并让Button类也看到图形库 模块和对象,而不必在button.py?
中导入它我花了很多时间阅读8小时并尝试解决这个问题。 任何帮助表示赞赏。
from graphics import *
from button import *
def __createButtons(win):
#create a list of buttons
bSpecs = [(2,1,'0'), (3,1,'.'),
(1,2,'1'), (2,2,'2'), (3,2,'3'), (4,2,'+'), (5,2,'-'),
(1,3,'4'), (2,3,'5'), (3,3,'6'), (4,3,'*'), (5,3,'/'),
(1,4,'7'), (2,4,'8'), (3,4,'9'), (4,4,'<-'), (5,4,'C')]
buttons = []
for (cx,cy,label) in bSpecs:
buttons.append(Button(win, Point(cx,cy), .75,.75,label))
###create larger = button
buttons.append(Button(win, Point(4.5,1), 1.75, .75, "="))
#activate all buttons
for b in buttons:
b.activate()
def main():
#create the window for the calculator
win = GraphWin("Calculator")
win.setCoords(0,0,6,7)
win.setBackground("slategray")
win= win
__createButtons(win)
main()
from graphics import *
class Button:
def __init__(self, win, center, width, height, label):
w,h = width/2.0, height/2.0
x,y = center.getX(), center.getY()
self.xmax, self.xmin = x+w, x-w
self.ymax, self.ymin = y+h, y-h
#Point function from graphics library
p1 = Point(self.xmin,self.ymin)
p2 = Point(self.xmax, self.ymax)
答案 0 :(得分:0)
简短回答:不,没有办法做到这一点。
graphics.py
超出了button.py
的范围,因为test_calc.py
导入的图片和test_calc.py
在button.py
的范围内。
但是,如果您确实要保存额外的行,则可以从from graphics import *
删除test_calc.py
,因为button.py
已导入graphics.py
。
答案 1 :(得分:0)
不,你不能这样做。如果按照您希望的方式工作,您将在button
内隐式地打破命名空间和范围,而不仅仅是test_calc
中的明确命中。
模块的范围(由该模块中定义的所有内容使用)由它导入的内容及其定义的内容(以及在设计不良的情况下,由后来的Monkey = patched)定义。从“导入我的东西中定义的内容”中添加内容是一个糟糕的主意。
这里的正确解决方案就是:
# If a package, explicit relative imports avoid checking the whole of sys.path
from .graphics import *
# IF not a package, use plain names without leading .s
from graphics import *
位于button.py
文件的顶部,因此它实际指定了从中获取API的位置(理想情况下,您明确列出要使用的名称,而不仅仅是*
,这有助于静态检查代码确定是否定义了所有名称,帮助维护者找出特定名称的来源,并避免两个模块提供相同名称并相互踩踏的风险。既然你已经做到了,那你就是金色的;您可以在graphics
中省略test_calc.py
内容的导入(假设test_calc.py
本身不使用它)。
如果出于某些疯狂的原因,这确实是必要的,最简单的方法是绕过import
语义并明确eval
button
的代码在同一范围内{包括graphics
内容。在test_calc.py
之后,在from graphics import *
之后,您明确open
和read
button.py
的内容(例如,button_source
)然后做:
eval(compile(button_source, button_path, 'exec'), globals())
将使用button.py
的全局范围(现在包括test_calc
内容)编译和评估graphics
的源代码,因此新定义的内容将在{{ 1}}的全局变量,并将那里定义的所有东西看作是它的“原生范围”。