繁体   English   中英

由于未定义的函数,脚本调用多个其他脚本错误

[英]Script calling multiple other scripts erroring due to undefined functions

我不确定的东西我确信会非常简单......

基本上,我正在尝试让我的第一个脚本调用/执行一堆其他脚本,但问题是我希望每个单独的脚本都包含自己的函数,而不是从第一个脚本调用...

第一个脚本/主脚本:

from datetime import date, timedelta
from sched import scheduler
from time import time, sleep, strftime
import random

s = scheduler(time, sleep)
random.seed()

def periodically(runtime, intsmall, intlarge, function):
     ## Get current time
    currenttime = strftime('%H:%M:%S')

    ## If currenttime is anywhere between 23:40 and 23:50 then...
    if currenttime > '23:40:00' and currenttime < '23:50:00':
        ## Call clear
        clear()
        ## Update time
        currenttime = strftime('%H:%M:%S')

    ## Idle time
    while currenttime > '23:40:00' and currenttime < '23:59:59' or currenttime >= '00:00:00' and currenttime < '01:30:00':
        ## Update time
        currenttime = strftime('%H:%M:%S')

    runtime += random.randrange(intsmall, intlarge)
    s.enter(runtime, 1, function, ())
    s.run()

def callscripts():
    print "Calling Functions"

    errors = open('ERROR(S).txt', 'a')
    try: 
        execfile("data/secondary.py")
    except Exception as e:
        errors.write(str(e))
        errors.write("""
""")         
    errors.close()


while True:
    periodically(2, -1, +1, callscripts)

以下是secondary.py

import win32con
from win32api import *
from win32gui import *

class WindowsBalloonTip:
    def __init__(self, title, msg):
        message_map = { win32con.WM_DESTROY: self.OnDestroy,}

        # Register the window class.
        wc = WNDCLASS()
        hinst = wc.hInstance = GetModuleHandle(None)
        wc.lpszClassName = 'PythonTaskbar'
        wc.lpfnWndProc = message_map # could also specify a wndproc.
        classAtom = RegisterClass(wc)

        # Create the window.
        style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
        self.hwnd = CreateWindow(classAtom, "Taskbar", style, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, hinst, None)
        UpdateWindow(self.hwnd)

        # Icons managment
        iconPathName = "icon1.ico" ## LOCATION TO THE ICON FILE
        icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
        try:
            hicon = LoadImage(hinst, iconPathName, win32con.IMAGE_ICON, 0, 0, icon_flags)
        except:
            hicon = LoadIcon(0, win32con.IDI_APPLICATION)
        flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
        nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, 'Tooltip')

        # Notify
        Shell_NotifyIcon(NIM_ADD, nid)
        Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, win32con.WM_USER+20, hicon, 'Balloon Tooltip', msg, 200, title))
        # self.show_balloon(title, msg)
        sleep(5)

        # Destroy
        DestroyWindow(self.hwnd)
        classAtom = UnregisterClass(classAtom, hinst)
    def OnDestroy(self, hwnd, msg, wparam, lparam):
        nid = (self.hwnd, 0)
        Shell_NotifyIcon(NIM_DELETE, nid)
        PostQuitMessage(0) # Terminate the app.

# Function
def balloon_tip(title, msg):
    w=WindowsBalloonTip(title, msg)


balloon_tip("test test", "Running")

def hi():
    print "hi"

hi()

错误:

global name 'WindowsBalloonTip' is not defined

完全错误:

Traceback (most recent call last):
  File "C:\Main.py", line 48, in <module>
    periodically(2, -1, +1, callscripts)
  File "C:\Main.py", line 27, in periodically
    s.run()
  File "C:\Python27\lib\sched.py", line 117, in run
    action(*argument)
  File "Main.py", line 34, in callscripts
    execfile("data/secondary.py")
  File "data/secondary.py", line 93, in <module>
    balloon_tip("test test", "Running")
  File "data/secondary.py", line 78, in balloon_tip
    w=WindowsBalloonTip(title, msg)
NameError: global name 'WindowsBalloonTip' is not defined

我该如何解决这个问题?

在此先感谢Hyflex

首先,

class WindowsBalloonTip:

应该

class WindowsBalloonTip(object):

因为前者是一个旧的样式类,它已经在Python 3中消失了,并且在Python 2.x的最新版本中仅用于向后兼容。

Ethan的回答是正确的,但如果你问这个问题,可能还不清楚。 这里有完整的解释。

当运行ballon_tip() ,它首先搜索本地命名空间 - balloon_tip()的命名空间 - 用于称为WindowsBalloonTip东西。 当它找不到它时,它会搜索全局命名空间。 因为你没有给任何提供globals参数execfile()它默认的命名空间callscripts()它不具有任何名字WindowsBaloonTip它的内部,和错误。

要解决这个问题,你可以将globals()作为参数传递给execfile ,但是这会污染你可能不想要的主脚本的全局命名空间。 您还可以将secondary.py中的所有内容声明为全局,但您可能不希望这样做,因为整点都是测试secondary.py。

问题是execfile execfile是一种丑陋的hack-y方式。 import更好。 一种解决方案是在secondary.py中写这样的东西:

def test_harness():
    balloon_tip("test test", "Running")
    hi()

然后,在主脚本中import secondary, traceback ,并像这样更改callscripts():

def callscripts():
        print "Calling Functions"
        errors = open("ERRORS(S).txt", "a")

        try:
            secondary.test_harness()
        except:
            errors.write(traceback.format_exc() + '\n')

编辑以回复评论:在脚本的顶部, import traceback ,然后:

def callscripts():
        print "Calling Functions"
        errors = open("ERRORS(S).txt", "a")

        try:
            execfile("data/secondary.py", {})
        except:
            errors.write(traceback.format_exc() + '\n')

问题是execfile。

基本上, execfile是一个带文件的花哨的exec 所以,当你调用execfile 'secondary.py'的Python执行的所有行secondary.py 在那里的execfile被称为上下文。 在这种情况下,它位于callscripts函数内部。

你可能想要的是subprocess

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM