Ошибка в Python: имя 'df' не определено - PullRequest
0 голосов
/ 16 июня 2020

Я новичок в python, много часов гуглил и ищу здесь, в stackoverflow. Но все еще есть проблема с моим кодом. Мне нужно запустить функцию foo во временном интервале и заполнить фрейм данных (например, каждую секунду добавлять метку времени в df). Я все еще получаю сообщение об ошибке: NameError: имя 'df' не определено

Спасибо за ответ.

Код :

    WAIT_TIME_SECONDS = 1


class ProgramKilled(Exception):
    pass

    df = pd.DataFrame([])

############################################################
############################################################
def foo():

    global df
    time1 = str(datetime.now())
    time2 = time1.replace(":", "_")
    print(time2)

    df2 = pd.DataFrame(data= {
    'timestamp': [time2],
    'cas_zapas_1_text': ['cas']
    })

    df = df.append(df2)

############################################################
############################################################
def signal_handler(signum, frame):
    raise ProgramKilled

class Job(threading.Thread):
    def __init__(self, interval, execute, *args, **kwargs):
        threading.Thread.__init__(self)
        self.daemon = False
        self.stopped = threading.Event()
        self.interval = interval
        self.execute = execute
        self.args = args
        self.kwargs = kwargs

    def stop(self):
                self.stopped.set()
                self.join()
    def run(self):
            while not self.stopped.wait(self.interval.total_seconds()):
                self.execute(*self.args, **self.kwargs)

if __name__ == "__main__":
    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)
    job = Job(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=foo)
    job.start()

    while True:
          try:
              time.sleep(1)
          except ProgramKilled:
              print("Program killed: running cleanup code")
              job.stop()
              break

Это результат скрипта:

runfile('C:/Users/Miro/.spyder-py3/untitled8.py', wdir='C:/Users/Miro/.spyder-py3')
Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\Users\Miro\Anaconda3\envs\spyder_4_0_1\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "C:\Users\Miro\.spyder-py3\untitled8.py", line 90, in run
    self.execute(*self.args, **self.kwargs)
  File "C:\Users\Miro\.spyder-py3\untitled8.py", line 68, in foo
    df = df.append(df2)
NameError: name 'df' is not defined
2020-06-16 08_29_31.920157
Program killed: running cleanup code

Ответы [ 4 ]

1 голос
/ 16 июня 2020

Определить global df перед class ProgramKilled(Exception):

0 голосов
/ 16 июня 2020

Спасибо всем за полезные и быстрые ответы. Это решение работает:

    WAIT_TIME_SECONDS = 1

global df
df = pd.DataFrame([])

class ProgramKilled(Exception):
    pass



############################################################
############################################################
def foo():

    global df
    time1 = str(datetime.now())
    time2 = time1.replace(":", "_")
    print(time2)

    df2 = pd.DataFrame(data= {
    'timestamp': [time2],
    'cas_zapas_1_text': ['cas']
    })

    df = df.append(df2)

############################################################
############################################################
def signal_handler(signum, frame):
    raise ProgramKilled

class Job(threading.Thread):
    def __init__(self, interval, execute, *args, **kwargs):
        threading.Thread.__init__(self)
        self.daemon = False
        self.stopped = threading.Event()
        self.interval = interval
        self.execute = execute
        self.args = args
        self.kwargs = kwargs

    def stop(self):
                self.stopped.set()
                self.join()
    def run(self):
            while not self.stopped.wait(self.interval.total_seconds()):
                self.execute(*self.args, **self.kwargs)

if __name__ == "__main__":
    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)
    job = Job(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=foo)
    job.start()

    while True:
          try:
              time.sleep(1)
          except ProgramKilled:
              print("Program killed: running cleanup code")
              job.stop()
              break
0 голосов
/ 16 июня 2020

Вы сделали df частью пространства имен ProgramKilled класса. Просто отключите его, и он станет переменной уровня модуля. Функции, которые хотят назначить его позже, используют global df, но вы уже правильно делаете эту часть в своем коде.

Просто измените на

class ProgramKilled(Exception):
    pass

df = pd.DataFrame([])
0 голосов
/ 16 июня 2020

Это означает, что df является переменной класса и не работает.

class ProgramKilled(Exception):
    pass

    df = pd.DataFrame([])

Если не переменная класса, вы должны изменить ее следующим образом:

class ProgramKilled(Exception):
    pass
...
if __name__ == "__main__":
...
df = pd.DataFrame([])
...

Если вам нужно ее определить вот, думаю, это не лучший выбор.

class ProgramKilled(Exception):
    global df
    df = pd.DataFrame([])
    pass
...