首页 > 解决方案 > 为什么孩子必须导入与父母相同的模块?

问题描述

我的主要 Python 程序(大多数是脚本)有详细的导入语句,我不想​​在我导入的模块中重复:

from __future__ import print_function       # Must be first import
from __future__ import with_statement       # Error handling for file opens

try:
    import tkinter as tk
    import tkinter.ttk as ttk
    import tkinter.font as font
    import tkinter.filedialog as filedialog
    import tkinter.messagebox as messagebox
    PYTHON_VER="3"
except ImportError: # Python 2
    import Tkinter as tk
    import ttk
    import tkFont as font
    import tkFileDialog as filedialog
    import tkMessageBox as messagebox
    PYTHON_VER="2"
# print ("Python version: ", PYTHON_VER)

import subprocess32 as sp
import sys
import os
import time
import datetime
from PIL import Image, ImageTk, ImageDraw, ImageFont
import pickle
from random import shuffle
import getpass                      # Get user name for file storage

import locale                       # To set thousands separator as , or .
locale.setlocale(locale.LC_ALL, '') # Use '' for auto

# mserve modules
import location as lc               # Home grown module

当我的程序/脚本接近 5,000 行时,我来到了光明面/(黑暗面?)并开始使用我自己设计的导入模块。第一个模块被称为location.py但是!,你瞧,我不得不重复已经在父程序中导入的导入语句mserve

EG 在标题:

from __future__ import print_function       # Must be first import
import getpass
import os
import pickle
import time

就在今晚,我正在写一个新功能:

import Tkinter as tk

class MsgDisplay:
    ''' Text Widget with status messages
    '''

    def __init__(self, title, toplevel, width, height):

        self.line_cnt = 0                   # Message lines displayed so far
        toplevel.update_idletasks()         # Get up-to-date window co-ords

        x = toplevel.winfo_x()
        y = toplevel.winfo_y()
        w = toplevel.winfo_width()
        h = toplevel.winfo_height()
        xd = (w/2) - (width/2)
        yd = (h/2) - (height/2)
        print('x:',x,'y:',y,'w:',w,'h:',h,
              'width:',width,'height:',height,'xd:',xd,'yd:',yd)
        
        ''' Mount message textbox window at centered in passed toplevel '''
        self.msg_top = tk.Toplevel()
        self.textbox = tk.Text(self.msg_top, height=height, width=width)
        self.msg_top.geometry('%dx%d+%d+%d'%(width, height, x + xd, y + yd))
#        self.textbox.columnconfigure(0, weight=1)
#        self.textbox.rowconfigure(0, weight=1)
        
        self.textbox.pack()
        self.textbox.insert(tk.END, "Just a text Widget\nin two lines\n")

    def Update(self, msg_list):
        self.textbox.insert(tk.END, "Just a text Widget\nin two lines\n")
        time.sleep(.1)
        
    def Close(self):
        self.msg_top.destroy()

我刚刚添加的新导入:

import Tkinter as tk

是捷径/软糖,因为生产版本需要:

try:
    import tkinter as tk
except ImportError: # Python 2
    import Tkinter as tk

在宣扬 python 2.7.12 已过时之前,请注意我使用的是 Ubuntu 16.04,其 EOL 为 2021。另请注意,我们在工作中使用 Windows 2008 Server,并且用 COBOL 编写的遗留系统很常见,所以谁在乎呢?

我一定做错了什么,因为导入的模块不应该导入父级已经做过的事情?在正常环境中,孩子应该知道/固有父母已经知道的东西。

顺便说一句,今晚的新课程“MsgDisplay”应该在父母而不是孩子。将类放在子类中比弄清楚子类如何调用父类更简单。

标签: pythonpython-import

解决方案


我一定是做错了什么,因为导入的模块不应该 > 来导入父级已经做过的事情?在正常环境中,孩子应该知道 > 父母已经知道的固有知识。

您正在描述一个类似 cpp 的包含系统,其中声明只是按顺序放置在单个翻译单元中。这不适用于python。在您使用它的任何地方都导入相同的模块是必要的。将导入视为将模块内容绑定到本地命名空间。如果您在模块 B 中使用模块 A 的内容,即使模块 C 已经导入 A 和稍后的 B,您也需要将其导入 B。不要太担心性能。一旦一个模块被 python 解释器加载,剩下的导入并不是很昂贵。


推荐阅读