2011-12-28 8 views
10

Używam skryptu Pythona z innego oprogramowania (zapewnia on interfejs Pythona do manipulowania strukturami danych).Wyłączanie asfla Pythona() bez flagi -0

Optymalizuję kod pod kątem szybkości i chciałbym sprawdzić, jaki wpływ na wydajność mają moje twierdzenia.

Nie mogę użyć python -O. Jakie mam inne opcje, aby programowo wyłączyć wszystkie potwierdzenia w kodzie Pythona? Zmienna __debug__ (który zdaje -O flagą) nie można przypisać :(

Odpowiedz

9

The docs say,

Wartość dla wbudowanej zmiennej [__debug__] jest określana podczas uruchamiania tłumacza.

Więc, jeśli nie można kontrolować, jak interpreter Pythona jest uruchomiona, to wygląda na to, że nie można wyłączyć assert.

Oto kilka innych opcji:

  1. Najbezpieczniejszym sposobem jest ręczne usunięcie wszystkich twierdzeń twierdzących.
  2. Jeśli wszystkie wypowiedzi dochodzić występują na liniach siebie, następnie może można je usunąć z

    sed -i 's/assert /pass #assert /g' script.py 
    

    Zauważ, że to magiel kodu jeśli inny kod przychodzi po assert. Na przykład, sed polecenie powyżej chciał komentować-out z return w linii tak:

    assert x; return True 
    

    które mogłyby zmienić logikę programu.

    Jeśli masz kod taki jak ten, najlepiej byłoby ręcznie usunąć gwarancje.

  3. Nie może być sposób, aby usunąć je programowo przez parsowania skryptu z modułem tokenize, ale pisząc taki program do Usuń twierdzi, może zająć więcej czasu niż zajęłoby ręcznie usunąć twierdzi, szczególnie jeśli to jest jednorazowa praca.

  4. Jeżeli drugi kawałek oprogramowania akceptuje .pyc plików, to istnieje świństwo, które wydaje się działać na moim komputerze, choć uwaga a Python core developer warns against this (patrz komentarz Éric Araujo w dniu 2011-09-17). Załóżmy, że Twój skrypt nazywa się script.py.

    • Bądź tymczasowy skrypt o nazwie, powiedzmy, temp.py:

      import script 
      
    • Uruchom python -O temp.py. To tworzy script.pyo.
    • Przenieś script.py i script.pyc (jeśli istnieje) z Twojego PYTHONPATH lub innego katalogu, który czyta inne oprogramowanie, aby znaleźć twój skrypt .
    • Zmień nazwę script.pyo ->script.pyc.

    Teraz, gdy inne oprogramowanie próbuje zaimportować skrypt będzie tylko znaleźć plik pyc, który posiada twierdzi usunięte.

    Na przykład, jeśli script.py wygląda następująco:

    assert False 
    print('Got here') 
    

    następnie uruchomiony python temp.py będzie teraz drukować Got here zamiast podnosząc AssertionError.

+0

mała poprawka: 's/assert/pass # assert/g. W przeciwnym razie gałęzie 'if' z tylko jedną instrukcją' assert' nie będą kompilować :) – pbp

+0

Dzięki; to jest dobry pomysł. – unutbu

0

Jak opisuje @unutbu, nie ma oficjalnego sposobu na zrobienie tego. Jednak prosta strategia jest zdefiniowanie flagę jak _test gdzieś (na przykład jako argumentu słowa kluczowego do funkcji lub jako zmienną globalną w module), a następnie uwzględnienie tego w swoich sprawozdaniach dochodzić następująco:

def f(x, _test=True): 
    assert not _test or x > 0 
    ... 

Następnie można wyłączyć potwierdzenia w tej funkcji, w razie potrzeby.

f(x, _test=False) 
1

Możesz to zrobić przy użyciu zmiennej środowiskowej, zgodnie z opisem w this other answer. Ustawienie PYTHONOPTIMIZE=1 jest równoważne uruchomieniu Pythona z opcją -O. Jako przykład, to działa w Blender 2,78, który osadza Python 3.5:

blender --python-expr 'assert False; print("foo")' 

PYTHONOPTIMIZE=1 blender --python-expr 'assert False; print("foo")' 

wydrukowaniu pierwszej dowodzić Traceback, a drugi po prostu drukuje „foo”.