2013-08-15 1 views
1

я снова неуверен с чем-то, что я уверен, что это будет очень просто ...Сценарий вызова несколько других сценариев erroring из-за неопределенные функции

В принципе, я пытаюсь сделать мой первый вызов сценария/выполнить кучу других сценариев, но проблема, я хочу, чтобы каждый индивидуальный сценарий, чтобы содержать свои собственные функции не будут вызываться из первого secript ...

первого сценария/главный сценарий:

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

+0

Пожалуйста, пост ** полный ** отслеживающей ошибки - информация, содержащиеся в нем призвана помочь отлаживайте свой код, чтобы опубликовать его. – Brionius

+0

Это полная трассировка ошибок из файла, если вы запускаете secondary.py самостоятельно, она запускается и работает нормально, но если вы запустите ее через main.py, как и предполагалось, она не сработает. Два сценария выше могут воссоздать ошибку отлично. – Ryflex

+0

Невозможно определить проблему без обратной трассировки. Но я думаю, вы можете посмотреть, как писать модули и использовать оператор import. Вместо того, чтобы определять функции в файле и вызывать эти функции на уровне модуля, вам следует просто импортировать ваш модуль из вашего первого скрипта, например 'import secondary', и вызвать в нем функции, такие как' secondary.balloon_tip() '. Это правильный способ написания модульного кода. – Iguananaut

ответ

3

Прежде всего,

class WindowsBalloonTip: 

должен быть

class WindowsBalloonTip(object): 

, потому что прежний старый класс стиль, который исчез в Python 3 и в последних версиях только 2.x Python для обратной совместимости.

Ответ Этана правильный, но, вероятно, неясно, если вы задаете этот вопрос. Полное описание: here.

Когда запущено ballon_tip(), оно сначала ищет локальное пространство имен - пространство имен balloon_tip() - для чего-то называемого WindowsBalloonTip. Когда он не может найти его, он ищет глобальное пространство имен. Поскольку параметр не был указан в execfile(), он по умолчанию использует пространство имен callscripts(), которое не имеет ни одного имени WindowsBaloonTip внутри него и ошибок.

Чтобы исправить это, вы можете передать globals() в качестве аргумента execfile, но это загрязнит глобальное пространство имен вашего основного скрипта, которого вы, вероятно, не хотите. Вы также можете объявить все внутри secondary.py глобальным, но вы, вероятно, не хотите этого делать, поскольку все дело в том, чтобы протестировать secondary.py.

Вопрос execfile. execfile - уродливый, взломанный способ сделать что-то. 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') 

EDIT в ответ на комментарий: в верхней части сценария, 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') 
+0

Спасибо за ваш очень подробный ответ, единственная проблема с этим - мне все еще нужно эффективно создавать функцию для запуска ряда функций ... В идеале я хочу, чтобы у меня была возможность вручную запустить secondary.py и это чтобы мгновенно вывести результаты, а затем, если запустить через main.py, чтобы он снова вывел те же результаты без необходимости специфического вызова определенных функций внутри импорта ... Это имеет смысл? – Ryflex

+1

Попробуйте 'execfile (script_path, {})'. Он работает на моей локальной машине. –

+0

как я мог бы использовать этот метод execfile, который вы только что упомянули, с тем же видом трассировки, что и ваш предыдущий ответ, так как полная трассировка будет лучше. – Ryflex

1

The problem is execfile.

В основном, execfile причудливое exec с файлом. Поэтому, когда вы вызываете execfile 'secondary.py', Python выполняет все строки secondary.pyв контексте вызова execfile. Который в этом случае находится внутри функции callscripts.

Возможно, вы захотите, чтобы это было subprocess.

+0

Можете ли вы привести пример использования подпроцесса в этих обстоятельствах; для работы с моим кодом, указанным выше? – Ryflex

Смежные вопросы