Domanda

Per qualche ragione questa funzione mi ha confuso:

def protocol(port):
    return port == "443" and "https://" or "http://"

Qualcuno può spiegare l'ordine di ciò che accade dietro le quinte per fare questo lavoro il modo in cui funziona.

ho capito come questo fino ho provato:

In entrambi A)

def protocol(port):
    if port == "443":
        if bool("https://"):
            return True
    elif bool("http://"):
        return True
    return False

o B)

def protocol(port):
    if port == "443":
        return True + "https://"
    else:
        return True + "http://"

E 'questa una sorta di caso particolare in Python, o sto completamente malinteso come affermazioni di lavoro?

È stato utile?

Soluzione

E 'un vecchio-ish linguaggio; inserendo parentesi per mostrare priorità,

(port == "443" and "https://") or "http://"

ritorna x and y y se x è truish, x se x è falsish; a or b, viceversa, i rendimenti a se è truish, altrimenti b.

Quindi, se port == "443" è vero, questo restituisce il RHS del and, vale a dire, "https://". In caso contrario, il and è falso, in modo che il or ottiene in gioco e torna ` "http: //"., la sua RHS

In Python moderna, un modo migliore per farlo tradurre questo vecchio-ish idioma è:

"https://" if port == "443" else "http://"

Altri suggerimenti

and ritorna l'operando di destra se la sinistra è vero. or ritorna l'operando di destra se la sinistra è falso. In caso contrario, entrambi restituiscono l'operando a sinistra. Si dice che fondono .

C and X or Y è la lunga corsa dei primi tentativi dagli utenti di Python per proxy per C ? X : Y

Per la maggior parte funziona, tranne se X è False - questo ha portato a molti bug nel codice Python, così nel Python FAQ , troverete la soluzione più corretta essendo (C and [X] or [Y])[0] perché una lista con un unico elemento, indipendentemente dal suo valore booleano valutato, è sempre True! Per esempio: è [None] True ma None non lo è. Esempio del PO sopra funziona perché la stringa che rappresenta X non è vuota.

Comunque, tutto questo è cambiato in Python 2.5, quando il ternario o operatore condizionale è stato aggiunto alla lingua, che consente di utilizzare il X if C else Y più pulito come affermato in altri post qui. Se si vede il codice utilizzando il vecchio formato, è perché l'utente è stato un lungo tempo di Python programmatore che non ha ancora adottato la nuova sintassi, hanno tagliato-n-incolla altro codice vecchio, o il loro datore di lavoro è ancora utilizzando 2.4.x ( o versioni precedenti), ecc.

Questa è una brutta hack che non è raccomandato. Funziona perché il corto circuito comportamento dei and e or e che restituisce l'uno dei loro argomenti, piuttosto che un valore booleano. Usando questa tecnica dà un rischio di introdurre bug difficili da trovare, in modo da non utilizzarlo in nuovo codice.

Ecco un esempio di come il linguaggio and/or può dare un risultato inaspettato:

>>> foo = 'foobar'
>>> bar = 'foobar'
>>> x = 0
>>> y = 1
>>> (foo == bar) and x or y   # Will this return the value of x if (foo == bar)?
1

Preferisco invece la notazione più recente:

return "https://" if port == "443" else "http://"

Si consiglia di leggere sulla "e / o trucco" di Python in questo articolo The Peculiar natura di And e Or in Python . E 'un po' come il IIF() in VBA o VB, o ?: in linguaggi di stile C.

Questa costruzione funziona perche 'e'' a dispiega il seguente codice:

A e B ->

if a:
  return b
else:
  return a

a o b ->

if a:
  return a
else:
  return b

Con tutte le buone risposte, ho trovato queste dichiarazioni aiutarmi a ricordare questo meglio e si adattano come i miei lavori cerebrali (e si spera per per un po 'là fuori):

  • “e" restituisce il primo falso oggetto (ad esempio, None, ‘’, [], (), {}, 0) o l'ultimo elemento se nessuno (ad esempio non False trovati)

  • “o" restituisce il primo vero elemento o l'ultima voce (ad esempio nessun vero trovati) **

In sintesi :

  • tutti restituiscono il primo elemento che decide l'esito della dichiarazione. (Nel peggiore dei casi, l'ultimo elemento della sequenza)

Si noti questa regola si applica anche ad un incatenato tutti "e" o tutti "o" istruzione

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top