2010-02-14 3 views
44

Ich musste die folgende Funktion schreiben, um beim Analysieren einer Zeichenfolge zu einer ganzen Zahl ordnungsgemäß fehlschlagen. Ich könnte mir vorstellen, dass Python etwas eingebaut hat, aber ich kann es nicht finden. Wenn nicht, gibt es einen pythonischen Weg, dies zu tun, der keine separate Funktion erfordert?Gibt es eine eingebaute oder mehr Pythonic Weg zu versuchen, eine Zeichenfolge zu einer ganzen Zahl zu analysieren

Die Lösung, die ich am Ende benutzte, war eine Modifikation von @ sharjeels Antwort. Das Folgende ist funktional identisch, aber ich denke, lesbarer.

def ignore_exception(exception=Exception, default_val=None): 
    """Returns a decorator that ignores an exception raised by the function it 
    decorates. 

    Using it as a decorator: 

    @ignore_exception(ValueError) 
    def my_function(): 
     pass 

    Using it as a function wrapper: 

    int_try_parse = ignore_exception(ValueError)(int) 
    """ 
    def decorator(function): 
    def wrapper(*args, **kwargs): 
     try: 
     return function(*args, **kwargs) 
     except exception: 
     return default_val 
    return wrapper 
    return decorator 
+2

Was haben Sie scheint gut. –

+1

@Paul Hildebrandt: Nicht nur gut, sondern die meisten Pythonic. –

+0

Ich denke, Ihr Beispiel ist zusätzlich wertvoll, um einen praktischen Nutzen für Dekorateure zu demonstrieren. –

Antwort

40

Dies ist ein ziemlich normales Szenario so dass ich einen „ignore_exception“ Dekorateur habe geschrieben, die für alle Arten von Funktionen arbeitet, die anmutig Ausnahmen statt andernfalls werfen:

def ignore_exception(IgnoreException=Exception,DefaultVal=None): 
    """ Decorator for ignoring exception from a function 
    e.g. @ignore_exception(DivideByZero) 
    e.g.2. ignore_exception(DivideByZero)(Divide)(2/0) 
    """ 
    def dec(function): 
     def _dec(*args, **kwargs): 
      try: 
       return function(*args, **kwargs) 
      except IgnoreException: 
       return DefaultVal 
     return _dec 
    return dec 

Verwendung in Ihrem Fall:

sint = ignore_exception(ValueError)(int) 
print sint("Hello World") # prints none 
print sint("1340") # prints 1340 
+0

Das ist schlau. Gute Antwort. –

+4

Während das ist schlau, und möglicherweise sogar nützlich, wenn Sie viele Funktionen damit dekorieren werden, beantwortet es nicht die Frage, wie in der Betreffzeile ausgedrückt. (Die Antwort auf die Betreffzeile lautet: Es gibt keinen eingebauten Code und der ursprüngliche Code des OP ist bereits der pythonischste Weg.) –

+0

Ja, ich stimme John zu, aber ich habe dich dafür gewählt, das Hackmesser zu bringen. –

1

int() ist der eingebaute und pythonische Weg, genau wie Sie dort haben.

Es ist in der Regel leichter und häufiger es aber direkt zu verwenden:

def show_square(user_input): 
    """Example of using int().""" 
    try: 
    num = int(user_input, 10) 
    except ValueError: 
    print "Error" # handle not-an-integer case 
    # or you may just want to raise an exception here 
    # or re-raise the ValueError 
    else: 
    print "Times two is", num * 2 

def another_example(user_input): 
    try: 
    num = int(user_input, 10) 
    except ValueError: 
    num = default 
    print "Times two is", num * 2 
7

Nein, es bereits perfekt ist. Der Parameter val könnte jedoch besser als Standard benannt werden.

in den offiziellen Dokumenten Dokumentierten einfach als int(x) -- x converted to integer

+1

Danke. Es ist bedauerlich, dass es keine integrierten Mittel gibt, um eine Ganzzahl zu analysieren, die keine Ausnahme auslöst. –

+6

@Christopher: Warum ist es unglücklich? Wie ist der Versuch - außer nicht eingebaut? –

+0

@Christopher: Dies ist, wie es ist Pythons "Kultur" und ich bin sicher, dass Sie das gleiche Muster an anderen Orten finden werden – u0b34a0f6ae

6

ich gehen würde:

def parse_int(s, base=10, val=None): 
if s.isdigit(): 
    return int(s, base) 
else: 
    return val 

Aber es ist mehr oder weniger das gleiche.

+1

Wusste nicht über str.isdigit. Das könnte nützlich sein. Vielen Dank. –

+0

Bitte beachten Sie die Antwort von abyx. Er hat recht und du solltest deinen Code verwenden, statt meiner. – Macarse

+2

Nicht nur ist der EAFP-Stil geeigneter und Pythonic in dieser Situation behandelt es negative ganze Zahlen während isdigit nicht. –

21

Das ist der pythonische Weg. In Python ist es üblich, EAFP-Stil zu verwenden - Leichter zu Vergeben als Erlaubnis.
Das bedeutet, Sie würden zuerst versuchen, und dann die Unordnung aufräumen, wenn nötig.

+0

@abyx: Ich mag die ersten beiden Sätze. Ich mag den dritten nicht. Wenn du sagst "Dann, wenn du sicher bist, dass du die Aktion ausführst", klingt es so, als ob du LBYL beschreibst, obwohl der erste Teil dieses Satzes mehr oder weniger korrekt für EAFP ist. Ich würde sagen "EAFP = versuche es einfach und bereinige das Durcheinander, wenn es schief geht". –

18
def intTryParse(value): 
    try: 
     return int(value), True 
    except ValueError: 
     return value, False 
+1

Schöne Lösung. Einfach und auf den Punkt. –

0
def parseint(string): 
    result = '0' 
    for x in string: 
     if x.isdigit(): 
     result+=x 
    else: 
     return int(result) 
    return int(result) 
+1

Schlechte Idee. Es erzeugt falsche Ergebnisse. Angenommen, der Einzug in Zeile 5 ist festgelegt, Parseint ('- 3') => 3; Parseint ('2by2') => 22; usw. Beachten Sie auch, dass die erste Rückkehr immer ausgeführt wird, da es keine Unterbrechung in der Schleife gibt. – Vroo

0
myList = ['12', '13', '5', 'hope', 'despair', '69','0', '1.2'] 

myInts = [int(x) for x in myList if x.isdigit()]