Python перезапуск программы при ошибке

I have a python script that starts a program and automates through it, continuously processing new data and saves to a pre-set directory. What is the recommended way to run the Python script forever,

When the python script crashes, the program is not running anymore, therefore the script cannot execute more lines of code.

You have 2 options:

  1. Make sure your python script doesn’t crash, which is very much recommended. You can do this by handling the exceptions thrown by your program.

Option 1

I assume you are new to python, so here is an example of a python script that handles an exception calls the same function again.

from time import sleep

def run_forever():
    try:
        # Create infinite loop to simulate whatever is running
        # in your program
        while True:
            print("Hello!")
            sleep(10)

            # Simulate an exception which would crash your program
            # if you don't handle it!
            raise Exception("Error simulated!")
    except Exception:
        print("Something crashed your program. Let's restart it")
        run_forever() # Careful.. recursive behavior
        # Recommended to do this instead
        handle_exception()

def handle_exception():
    # code here
    pass

run_forever()
  1. If you want to restart the python script you would need another python script (assuming you want to do this with python) that checks if the process is still alive and if not then run it again with python.

Option 2

This is the script that starts another python script called ‘test.py’ via the command python test.py.
Make sure you have the right file path, if you put the scripts in the same folder, you usually don’t need the full path and only the script name.

Notably, make sure that command ‘python‘ is recognized by your system, it could in some cases by ‘python3’

script_starter.py

from subprocess import run
from time import sleep

# Path and name to the script you are trying to start
file_path = "test.py" 

restart_timer = 2
def start_script():
    try:
        # Make sure 'python' command is available
        run("python "+file_path, check=True) 
    except:
        # Script crashed, lets restart it!
        handle_crash()

def handle_crash():
    sleep(restart_timer)  # Restarts the script after 2 seconds
    start_script()

start_script()

In case you are interested in the code I used for the test file: ‘test.py’, I post it here.

test.py

from time import sleep
while True:
    sleep(1)
    print("Hello")
    raise Exception("Hello")

I have a program that queries an API every few seconds. Each response triggers a few functions which themselves make some calls to websites and such — calls that I don’t want to blindly trust to succeed. If I catch an exception in foo(), for example, or even in a function that foo() calls, is it possible to restart the program entirely in the except block? Essentially, I want to call queryRepeatedly() upon an exception in one of its sub-functions, without keeping the previous call on the stack.

Of course, I could return marker values and solve this another way, but the program is structured in a way such that the above approach seems much simpler and cleaner.

# Sample "main" function that I want to call
def queryRepeatedly():
    while True:
        foo()
        bar()
        baz()
        time.sleep(15)

def foo():
    # do something
    try:
        foo2() # makes a urllib2 call that I don't trust
    except:
        #restart queryRepeatedly

queryRepeatedly()

pppery's user avatar

pppery

3,64920 gold badges31 silver badges44 bronze badges

asked Jul 8, 2013 at 18:02

vroomfondel's user avatar

3

To restart anything, just use a while loop outside the try. For example:

def foo():
    while True:
        try:
            foo2()
        except:
            pass
        else:
            break

And if you want to pass the exception up the chain, just do this in the outer function instead of the inner function:

def queryRepeatedly():
    while True:
        while True:
            try:
                foo()
                bar()
                baz()
            except:
                pass
            else:
                break
        time.sleep(15)

def foo():
    foo2()

All that indentation is a little hard to read, but it’s easy to refactor this:

def queryAttempt()
    foo()
    bar()
    baz()

def queryOnce():
    while True:
        try:
            queryAttempt()
        except:
            pass
        else:
            break

def queryRepeatedly():
    while True:
        queryOnce()
        time.sleep(15)

But if you think about it, you can also merge the two while loops into one. The use of continue may be a bit confusing, but see if you like it better:

def queryRepeatedly():
    while True:
        try:
            foo()
            bar()
            baz()
        except:
            continue
        time.sleep(15)

Daniel Walker's user avatar

answered Jul 8, 2013 at 18:05

abarnert's user avatar

abarnertabarnert

347k48 gold badges588 silver badges657 bronze badges

2

Refactor this — you’ll get a stackoverflow error sooner or later if you have enough failures.

queryRepeatedly should just be query. It should return void and throw exceptions on failures.

Wrap in something that looks like this, your true queryRepeatedly function?

while True:
    try:
        query()
    except:
        #handle
    time.sleep(15)

All looping, no recursion needed.

Note that you must think carefully about how much of your program you need to restart. From your question it sounded like your actual problem was ensuring the query could try again if it sporadically fails, which is what my solution ensures. But if you want to clean up program resources — say, bounce SQL connections, which may have broken — then you need to think more carefully about how much of your program you need to «restart.» In general you need to understand why your query failed to know what to fix, and in the extreme case, the right thing to do is an email or SMS to someone on call who can inspect the situation and write an appropriate patch or fix.

answered Jul 8, 2013 at 18:06

djechlin's user avatar

djechlindjechlin

58.9k33 gold badges160 silver badges284 bronze badges

12

First make two files.

One file called run.py and one called forever.py and put them in the same folder.

Go to your terminal within that folder and type chmod +x forever.py

run.py

whatever code you want to run

forever.py

#!/usr/local/lib/python3.7
from subprocess import Popen
import sys

filename = sys.argv[1]
while True:
    print("nStarting " + filename)
    p = Popen("python3 " + filename, shell=True)
    p.wait()

Open a terminal window from the folder and type this:

python3 ./forever.py run.py

to start run.py and if it fails or has an exception, it’ll just start over again.

You now have a template to make sure if a file crashes or has an exception, you can restart it without being around. If this helps you, please give me a vote!

Olivier's user avatar

answered Mar 1, 2020 at 4:50

Cody Krecicki's user avatar

0

In your exception make a recursive call

except:
      queryRepeatedly()

answered Jul 8, 2013 at 18:06

sedavidw's user avatar

sedavidwsedavidw

10.7k13 gold badges56 silver badges92 bronze badges

4

I have a program that queries an API every few seconds. Each response triggers a few functions which themselves make some calls to websites and such — calls that I don’t want to blindly trust to succeed. If I catch an exception in foo(), for example, or even in a function that foo() calls, is it possible to restart the program entirely in the except block? Essentially, I want to call queryRepeatedly() upon an exception in one of its sub-functions, without keeping the previous call on the stack.

Of course, I could return marker values and solve this another way, but the program is structured in a way such that the above approach seems much simpler and cleaner.

# Sample "main" function that I want to call
def queryRepeatedly():
    while True:
        foo()
        bar()
        baz()
        time.sleep(15)

def foo():
    # do something
    try:
        foo2() # makes a urllib2 call that I don't trust
    except:
        #restart queryRepeatedly

queryRepeatedly()

pppery's user avatar

pppery

3,64920 gold badges31 silver badges44 bronze badges

asked Jul 8, 2013 at 18:02

vroomfondel's user avatar

3

To restart anything, just use a while loop outside the try. For example:

def foo():
    while True:
        try:
            foo2()
        except:
            pass
        else:
            break

And if you want to pass the exception up the chain, just do this in the outer function instead of the inner function:

def queryRepeatedly():
    while True:
        while True:
            try:
                foo()
                bar()
                baz()
            except:
                pass
            else:
                break
        time.sleep(15)

def foo():
    foo2()

All that indentation is a little hard to read, but it’s easy to refactor this:

def queryAttempt()
    foo()
    bar()
    baz()

def queryOnce():
    while True:
        try:
            queryAttempt()
        except:
            pass
        else:
            break

def queryRepeatedly():
    while True:
        queryOnce()
        time.sleep(15)

But if you think about it, you can also merge the two while loops into one. The use of continue may be a bit confusing, but see if you like it better:

def queryRepeatedly():
    while True:
        try:
            foo()
            bar()
            baz()
        except:
            continue
        time.sleep(15)

Daniel Walker's user avatar

answered Jul 8, 2013 at 18:05

abarnert's user avatar

abarnertabarnert

347k48 gold badges588 silver badges657 bronze badges

2

Refactor this — you’ll get a stackoverflow error sooner or later if you have enough failures.

queryRepeatedly should just be query. It should return void and throw exceptions on failures.

Wrap in something that looks like this, your true queryRepeatedly function?

while True:
    try:
        query()
    except:
        #handle
    time.sleep(15)

All looping, no recursion needed.

Note that you must think carefully about how much of your program you need to restart. From your question it sounded like your actual problem was ensuring the query could try again if it sporadically fails, which is what my solution ensures. But if you want to clean up program resources — say, bounce SQL connections, which may have broken — then you need to think more carefully about how much of your program you need to «restart.» In general you need to understand why your query failed to know what to fix, and in the extreme case, the right thing to do is an email or SMS to someone on call who can inspect the situation and write an appropriate patch or fix.

answered Jul 8, 2013 at 18:06

djechlin's user avatar

djechlindjechlin

58.9k33 gold badges160 silver badges284 bronze badges

12

First make two files.

One file called run.py and one called forever.py and put them in the same folder.

Go to your terminal within that folder and type chmod +x forever.py

run.py

whatever code you want to run

forever.py

#!/usr/local/lib/python3.7
from subprocess import Popen
import sys

filename = sys.argv[1]
while True:
    print("nStarting " + filename)
    p = Popen("python3 " + filename, shell=True)
    p.wait()

Open a terminal window from the folder and type this:

python3 ./forever.py run.py

to start run.py and if it fails or has an exception, it’ll just start over again.

You now have a template to make sure if a file crashes or has an exception, you can restart it without being around. If this helps you, please give me a vote!

Olivier's user avatar

answered Mar 1, 2020 at 4:50

Cody Krecicki's user avatar

0

In your exception make a recursive call

except:
      queryRepeatedly()

answered Jul 8, 2013 at 18:06

sedavidw's user avatar

sedavidwsedavidw

10.7k13 gold badges56 silver badges92 bronze badges

4

How do you make a python program automatically restart itself? So let’s say there is a really simple program like:

var = input("Hi! I like cheese! Do you like cheese?").lower()
if var == "yes":
    print("That's awesome!")

Now, in a Python Shell, you would have to press either the Run button and then ‘Run Module (F5)’ or just the F5 key on your keyboard. That is the first time you run it. When the program ended, you would go back to your Cheese.py file and then press F5 to run the program again.

Everybody with me here?
OK, so my question is, how do you make the program restart itself automatically without you having to manually do it?

martineau's user avatar

martineau

117k25 gold badges161 silver badges290 bronze badges

asked Mar 15, 2016 at 17:42

DavidEclipse's user avatar

3

It depends on what you mean by «restart itself.» If you just want to continuously execute the same code, you can wrap it in a function, then call it from within a while True loop, such as:

>>> def like_cheese():
...     var = input("Hi! I like cheese! Do you like cheese?").lower()  # Corrected the call to `.lower`.
...     if var == "yes":
...         print("That's awesome!")
...
>>> while True:
...     like_cheese()
...
Hi! I like cheese! Do you like cheese?yes
That's awesome!
Hi! I like cheese! Do you like cheese?yes
That's awesome!

If you want to actually restart the script you can execute the script again, replacing the current process with the new one by doing the following:

#! /bin/env python3
import os
import sys

def like_cheese():
    var = input("Hi! I like cheese! Do you like cheese?").lower()
    if var == "yes":
        print("That's awesome!")

if __name__ == '__main__':
    like_cheese()
    os.execv(__file__, sys.argv)  # Run a new iteration of the current script, providing any command line args from the current iteration.

This will continuously re-run the script, providing the command line arguments from the current version to the new version. A more detailed discussion of this method can be found in the post «Restarting a Python Script Within Itself» by Petr Zemek.

One item that this article notes is:

If you use the solution above, please bear in mind that the exec*()
functions cause the current process to be replaced immediately,
without flushing opened file objects. Therefore, if you have any
opened files at the time of restarting the script, you should flush
them using f.flush() or os.fsync(fd) before calling an exec*()
function.

answered Mar 15, 2016 at 17:55

Deacon's user avatar

DeaconDeacon

3,5151 gold badge29 silver badges52 bronze badges

1

or you can try

$ chmod a+x "name".py

Then, you can run the script via

$ ./daemon.py

In such a situation, to restart the script, use the following code:

os.execv(__file__, sys.argv)

Otherwise, when you run the script via

$ python daemon.py

use this code:

os.execv(sys.executable, ['python'] + sys.argv)

Either way, do not forget to import the sys module

L_J's user avatar

L_J

2,29510 gold badges24 silver badges28 bronze badges

answered Jul 14, 2018 at 16:32

user10081708's user avatar

0

I use terminal on my Mac to re-start some of my python scripts with the function below.

import subprocess  
def run_again(cmd):
    subprocess.call(["bash", "-c", "source ~/.profile; " + cmd])  

Note: Don’t forget the space character after «profile;» or the function may fail silently!

Then at the bottom of my script to be re-started:

if some_condition:  
    run_again("python my_script.py %s" % my_new_arguments)  

For the original question about the cheese script:

if var != 'yes':  
    run_again("python my_cheese_script.py")  

answered Oct 13, 2017 at 18:13

exbctel's user avatar

exbctelexbctel

1951 silver badge9 bronze badges

You can just use a shell script like test.sh and make sure in your linux terminal you chmod +x test.sh

As for the code:

#!/bin/bash

while :
do
  sleep 5
  gnome-terminal --wait -- sh -c "python3 myscript.py 'myarg1'"
done

answered Nov 17, 2020 at 20:46

Chris's user avatar

ChrisChris

17.3k15 gold badges57 silver badges76 bronze badges

You can wrap something in while True: to make it execute repeatedly, as True will always evaluate to True, like this:

while True:
    var = input("Hi! I like cheese! Do you like cheese?").lower() # <-- You had missed parentheses here        
    if var == "yes":
        print("That's awesome!")

There’s another issue with your code though; you haven’t called lower by putting parentheses after it.

answered Mar 15, 2016 at 17:44

Aaron Christiansen's user avatar

7

How do you make a python program automatically restart itself? So let’s say there is a really simple program like:

var = input("Hi! I like cheese! Do you like cheese?").lower()
if var == "yes":
    print("That's awesome!")

Now, in a Python Shell, you would have to press either the Run button and then ‘Run Module (F5)’ or just the F5 key on your keyboard. That is the first time you run it. When the program ended, you would go back to your Cheese.py file and then press F5 to run the program again.

Everybody with me here?
OK, so my question is, how do you make the program restart itself automatically without you having to manually do it?

martineau's user avatar

martineau

117k25 gold badges161 silver badges290 bronze badges

asked Mar 15, 2016 at 17:42

DavidEclipse's user avatar

3

It depends on what you mean by «restart itself.» If you just want to continuously execute the same code, you can wrap it in a function, then call it from within a while True loop, such as:

>>> def like_cheese():
...     var = input("Hi! I like cheese! Do you like cheese?").lower()  # Corrected the call to `.lower`.
...     if var == "yes":
...         print("That's awesome!")
...
>>> while True:
...     like_cheese()
...
Hi! I like cheese! Do you like cheese?yes
That's awesome!
Hi! I like cheese! Do you like cheese?yes
That's awesome!

If you want to actually restart the script you can execute the script again, replacing the current process with the new one by doing the following:

#! /bin/env python3
import os
import sys

def like_cheese():
    var = input("Hi! I like cheese! Do you like cheese?").lower()
    if var == "yes":
        print("That's awesome!")

if __name__ == '__main__':
    like_cheese()
    os.execv(__file__, sys.argv)  # Run a new iteration of the current script, providing any command line args from the current iteration.

This will continuously re-run the script, providing the command line arguments from the current version to the new version. A more detailed discussion of this method can be found in the post «Restarting a Python Script Within Itself» by Petr Zemek.

One item that this article notes is:

If you use the solution above, please bear in mind that the exec*()
functions cause the current process to be replaced immediately,
without flushing opened file objects. Therefore, if you have any
opened files at the time of restarting the script, you should flush
them using f.flush() or os.fsync(fd) before calling an exec*()
function.

answered Mar 15, 2016 at 17:55

Deacon's user avatar

DeaconDeacon

3,5151 gold badge29 silver badges52 bronze badges

1

or you can try

$ chmod a+x "name".py

Then, you can run the script via

$ ./daemon.py

In such a situation, to restart the script, use the following code:

os.execv(__file__, sys.argv)

Otherwise, when you run the script via

$ python daemon.py

use this code:

os.execv(sys.executable, ['python'] + sys.argv)

Either way, do not forget to import the sys module

L_J's user avatar

L_J

2,29510 gold badges24 silver badges28 bronze badges

answered Jul 14, 2018 at 16:32

user10081708's user avatar

0

I use terminal on my Mac to re-start some of my python scripts with the function below.

import subprocess  
def run_again(cmd):
    subprocess.call(["bash", "-c", "source ~/.profile; " + cmd])  

Note: Don’t forget the space character after «profile;» or the function may fail silently!

Then at the bottom of my script to be re-started:

if some_condition:  
    run_again("python my_script.py %s" % my_new_arguments)  

For the original question about the cheese script:

if var != 'yes':  
    run_again("python my_cheese_script.py")  

answered Oct 13, 2017 at 18:13

exbctel's user avatar

exbctelexbctel

1951 silver badge9 bronze badges

You can just use a shell script like test.sh and make sure in your linux terminal you chmod +x test.sh

As for the code:

#!/bin/bash

while :
do
  sleep 5
  gnome-terminal --wait -- sh -c "python3 myscript.py 'myarg1'"
done

answered Nov 17, 2020 at 20:46

Chris's user avatar

ChrisChris

17.3k15 gold badges57 silver badges76 bronze badges

You can wrap something in while True: to make it execute repeatedly, as True will always evaluate to True, like this:

while True:
    var = input("Hi! I like cheese! Do you like cheese?").lower() # <-- You had missed parentheses here        
    if var == "yes":
        print("That's awesome!")

There’s another issue with your code though; you haven’t called lower by putting parentheses after it.

answered Mar 15, 2016 at 17:44

Aaron Christiansen's user avatar

7

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

import numpy as np

def main():
    np.load('File.csv')

for i in range(1, 10):
    try:
        main()
    except Exception as e:
        print e
        print 'Restarting!'
        main()

3 ответа

Лучший ответ

Чтобы сделать это внутри Python, используйте try/except соответственно:

import numpy as np

def main():
    np.load('File.csv')

for i in range(1, 10):
    try:
        main()
    except Exception as e:
        print e
        print 'Restarting!'
        continue
    else:
        break

Для простых инструкций это работает, но если ваш код становится более сложным, помещение всей функции main() в блок try/except может скрыть исключения и затруднить отладку вашей программы. Таким образом, я бы порекомендовал обработать перезапуск вне питона, например в скрипте bash.


2

dron22
8 Апр 2016 в 13:53

Вы можете очень хорошо использовать рекурсивную функцию здесь для автоматического перезапуска кода. используйте setrecursionlimit (), чтобы определить количество попыток следующим образом:

import numpy as np
import sys
sys.setrecursionlimit(10)  # set recursion depth limit


def main():
    try:
        a = np.load('file.csv')
        if a:
            return a
    except Exception as e:
        return main()

result = main()
print result

Надеюсь это поможет :)


1

hemraj
8 Апр 2016 в 14:16

Для чего-то подобного (подключение к веб-странице) часто лучше устанавливать верхний предел на основе времени, а не количества попыток подключения. Так что используйте цикл while:

import numpy as np
import time

def main():
    np.load('file.csv')

start = time.time()
stop = start + 5
attempts = 0
result = 'failed'

while True:
    if time.time()<stop:
        try:
            main()
        except Exception as e:
            attempts += 1
            print e
            time.sleep(0.1) # optional
            print 'Restarting!'
            continue
        else:
            result = 'succeeded'
    print 'Connection %s after %i attempts.' % (result, attempts)
    break

Необязательно: я включил паузу в 100 мс после каждой неудачной попытки. Это может помочь с установлением соединения иногда.

Затем оберните все это в функцию, которую вы можете использовать в будущем для других проектов:

# retry.py

import time

def retry(f, seconds, pause = 0):
    start = time.time()
    stop = start + seconds
    attempts = 0
    result = 'failed'

    while True:
        if time.time()<stop:
            try:
                f()
            except Exception as e:
                attempts += 1
                print e
                time.sleep(pause)
                print 'Restarting!'
                continue
            else:
                result = 'succeeded'
        print '%s after %i attempts.' % (result, attempts)
        break

Теперь просто сделай это:

import numpy as np
from retry import retry

def main():
    np.load('file.csv')

retry(main, 5, 0.1)

Процедура тестирования:

class RetryTest():
    def __init__(self, succeed_on = 0, excp = Exception()):
        self.succeed_on = succeed_on
        self.attempts = 0
        self.excp = excp
    def __call__(self):
        self.attempts += 1
        if self.succeed_on == self.attempts:
            self.attempts = 0
        else:
            raise self.excp

retry_test1 = RetryTest(3)
retry(retry_test1, 5, 0.1)
# succeeded after 3 attempts.
retry_test2 = RetryTest()
retry(retry_test2, 5, 0.1)
# failed after 50 attempts.


1

Rick supports Monica
8 Апр 2016 в 23:32

Sometimes, you may wish to check within a script when a configuration file or the script itself changes, and if so, then automatically restart the script. In this post, you will see a way of doing this in Python.

Consider the following scenario. You have a Python script that runs as a daemon and regularly performs the prescribed tasks. Examples may be a web server, a logging service, and a system monitor. When the script starts, it reads its configuration from a file, and then enters an infinite loop. In this loop, it waits for inputs from the environment and acts upon them. For example, a web server may react to a request for a page, which results into sending a response to the user.

From time to time, it may be necessary to restart the script. For example, if you fix a bug in it or change its configuration. One way of doing so is to kill the script and run it again. However, this requires manual intervention, which you may forget to do. When you fix a vulnerability in the script, you want to be sure that you do not forget to restart the script. Otherwise, someone may exploit the vulnerability if you did not restart the script. It would be nice if there existed a way of restarting the script within itself after it detected that its sources or a configuration file changed. In the rest of this post, we will show such a way.

For the purpose of the present post, let us assume that the script has the following structure:

# Parse the arguments and configuration files.

while True:
    # Wait for inputs and act on them.
    # ...

That is, it processes the arguments and loads the configuration from the configuration files. After that, the script waits for inputs and processes them in an infinite loop.

Next, we describe how to watch files for changes. After that, we show how to restart the script.

Checking Watched Files For Changes

First, we define the paths to the files whose change we want to watch:

WATCHED_FILES = [GLOBAL_CONFIG_FILE_PATH, LOCAL_CONFIG_FILE_PATH, __file__]

We watch the global configuration file, the local configuration file, and the script itself, whose path can be obtained from the special global variable __file__. When the script starts, we get and store the time of the last modification of these files by using os.path.getmtime():

from os.path import getmtime

WATCHED_FILES_MTIMES = [(f, getmtime(f)) for f in WATCHED_FILES]

Then, we add a check if any of these files have changed into the main loop:

while True:
    for f, mtime in WATCHED_FILES_MTIMES:
        if getmtime(f) != mtime:
            # Restart the script.

    # Wait for inputs and act on them.
    # ...

If either of the files that we watch has changed, we restart the script. The restarting is described next.

Restarting the Script

We restart the script by utilizing one of the exec*() functions from the os module. The exact version and arguments depend on how you run the script. For example, on Linux or Mac OS, you can make the file executable by putting the following line to the top of the file

#!/usr/bin/env python

and executing

$ chmod a+x daemon.py

Then, you can run the script via

$ ./daemon.py

In such a situation, to restart the script, use the following code:

os.execv(__file__, sys.argv)

Otherwise, when you run the script via

$ python daemon.py

use this code:

os.execv(sys.executable, ['python'] + sys.argv)

Either way, do not forget to import the sys module:

import sys

To explain, the arguments of os.execv() are the program to replace the current process with and arguments to this program. The __file__ variable holds a path to the script, sys.argv are arguments that were passed to the script, and sys.executable is a path to the Python executable that was used to run the script.

The os.execv() function does not return. Instead, it starts executing the current script from its beginning, which is what we want.

Concluding Remarks

If you use the solution above, please bear in mind that the exec*() functions cause the current process to be replaced immediately, without flushing opened file objects. Therefore, if you have any opened files at the time of restarting the script, you should flush them using f.flush() or os.fsync(fd) before calling an exec*() function.

Of course, the presented solution is only one of the possible ways of restarting a Python script. Depending on the actual situation, other approaches, like killing the script externally and starting it afterwards, may be more suitable for you. Moreover, there exist other methods of checking whether a watched file has changed and acting upon such a change. If you know of another way of restarting a Python program within itself, please share it by posting a comment.

Complete Source Code

The complete source code for this post is available on GitHub.

Понравилась статья? Поделить с друзьями:
  • Python как изменить раскладку клавиатуры
  • Python как изменить название переменной во всем коде
  • Python google translate error
  • Python base64 binascii error incorrect padding
  • Pytest error not found