从另一个文件调用函数,该文件包含在主文件中声明的变量

时间:2017-12-22 14:53:25

标签: python

我正在Tkinter中创建简单的记事本程序。我决定将函数放在单独的文件中。如果函数对主文件中声明的变量进行操作,是否可能? 这是代码的片段: main.py

from tkinter import *
from otherfile import cut
root = Tk()
....
menu_edit.add_command(label='Cut', compound='left', command=cut)
...
main_text = Text(root, wrap ='word')
main_text.pack(expand='yes', fill = 'both')

现在我有了otherfile.py

def cut():
    main_text.event_generate('<<Cut>>')
    return 'break'

一旦我运行它,我会得到: Tkinter回调中的例外

Traceback (most recent call last):
  File "C:...\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\....otherfile.py", line 3, in cut
    main_text.event_generate('<<Cut>>')
NameError: name 'main_text' is not defined

所以我猜otherfile.py不理解main.py中定义的main_text。有没有办法绕过它并允许我将所有函数放在不同的py文件中?

3 个答案:

答案 0 :(得分:1)

int [] Counter_Event = new int [46]; for (int xCount = 0; xCount < Counter_Event.Length; xCount++) { Counter_Event[xCount] = (int)Math.Round((double)(xCount * 10000)); } 正在尝试使用其他文件中的全局变量。即使你找到了解决循环进口问题的方法,但这也是一种混乱的方式。编写独立于全局变量操作的函数会更好。首先,它使修改和测试更容易。当您需要处理分配cutcommand=function变量时,functools.partial是您的朋友。

function

然后在主文件中,首先声明def cut(tk_text_obj): tk_text_obj.event_generate('<<Cut>>') return 'break' ,然后使用main_text创建一个不带参数的可调用对象。

functools.partial

答案 1 :(得分:0)

有可能。您应该在main中导入otherfile或修改otherfile.cut方法以接受main_text作为方法参数。第二个选项取决于menu_edit.add_command是否允许将参数传递给命令。

我认为你有两个问题。

  1. 圆形进口是一种真正的痛苦。
  2. 在模块导入期间调用模块级别声明的所有内容。
  3. 我相信下面的例子就是你的情况。

    a.py:

    import b
    commands = []
    
    def add_command(cmd):
        commands.append(cmd)
    
    def run_commands():
        for cmd in commands:
            print cmd()
    
    def local_cmd():
        return 'local cmd output'
    
    if __name__ == '__main__':
        add_command(local_cmd)
        add_command(b.b_cmd)
        run_commands()
    

    b.py:

    import a
    
    def b_cmd():
       l = a.local_cmd()
       return 'B %s B' % l
    

    使用python a.py时,上面的代码段按预期工作。

    但是当你跳过if __name__ == '__main__':时,你会发现类似的情况。脚本失败,因为当您在a中导入b时,add_command(b.b_cmd)中的a被调用,但b尚未导入。

答案 2 :(得分:0)

使用全局变量是一种不好的做法和头痛。我建议修改cut()以获取参数:

# otherfile.py
def cut(text_control):
    text_control.event_generate('<<Cut>>')
    return 'break'

然后在主模块中,将其称为:

# main.py
menu_edit.add_command(label='Cut', compound='left', command=lambda: cut(main_text))

这样,你以后就不必处理麻烦了。此外,如果需要,现在可以将函数cut()用于其他文本框。