Come è il 'è' parola chiave implementato in Python?
-
24-10-2019 - |
Domanda
... la parola is
che può essere utilizzato per l'uguaglianza nelle stringhe.
>>> s = 'str'
>>> s is 'str'
True
>>> s is 'st'
False
Ho provato entrambi __is__()
e __eq__()
, ma non ha funzionato.
>>> class MyString:
... def __init__(self):
... self.s = 'string'
... def __is__(self, s):
... return self.s == s
...
>>>
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work
False
>>>
>>> class MyString:
... def __init__(self):
... self.s = 'string'
... def __eq__(self, s):
... return self.s == s
...
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work, but again failed
False
>>>
Soluzione
stringhe di test con is
funziona solo quando le stringhe sono internati. A meno che tu non sappia quello che stai facendo e in modo esplicito internati le corde si dovrebbe non uso is
sulle stringhe.
test is
per identity , non uguaglianza . Ciò significa che Python confronta semplicemente l'indirizzo di memoria un oggetto risiede in. is
risponde fondamentalmente la domanda "Devo due nomi per lo stesso oggetto?" -. Sovraccarico che non avrebbe alcun senso
Per esempio, ("a" * 100) is ("a" * 100)
è false . Di solito Python scrive ogni stringa in una posizione di memoria diversa, internato accade soprattutto per le stringhe.
Altri suggerimenti
L'operatore is
equivale a confrontare i valori id(x)
. id
è attualmente implementato da usare puntatori come il confronto. Quindi non si può sovraccaricare is
per sé, e per quanto ne so non è possibile sovraccaricare id
sia.
Quindi, non si può. Insolito in Python, ma è così.
Il Python is
test di parole chiave oggetto identità. NON deve usare per prova per l'uguaglianza di stringa. Può sembrare a lavorare spesso perché le implementazioni di Python, come quelle di molti linguaggi di altissimo livello, esegue "internato" di stringhe. Vale a dire che i letterali e valori stringa sono memorizzati internamente in un elenco hash e quelle che sono identiche sono resi come riferimenti allo stesso oggetto. (Questo è possibile perché le stringhe di Python sono immutabili).
Tuttavia, come con qualsiasi dettaglio di implementazione, non si dovrebbe fare affidamento su questo. Se si desidera verificare per l'uso uguaglianza l'operatore ==. Se veramente si vuole prova per identità di un oggetto quindi utilizzare is
--- e sarei in difficoltà a venire con un caso in cui si dovrebbe preoccuparsi di identità di un oggetto stringa. Purtroppo non è possibile contare su se due stringhe sono in qualche modo "volutamente" riferimenti a oggetti identici a causa della suddetta internato.
La parola chiave is
confronta gli oggetti (o, meglio, a confronto se due riferimenti sono allo stesso oggetto).
Il che è, credo, perché non c'è alcun meccanismo per fornire la propria implementazione.
Capita di lavorare a volte su stringhe perché i negozi Python stringhe 'abilmente', in modo tale che quando si crea due stringhe identiche sono immagazzinate in un unico oggetto.
>>> a = "string"
>>> b = "string"
>>> a is b
True
>>> c = "str"+"ing"
>>> a is c
True
È possibile, auspicabilmente, vedere il riferimento vs confronto dei dati in un semplice 'copia' esempio:
>>> a = {"a":1}
>>> b = a
>>> c = a.copy()
>>> a is b
True
>>> a is c
False
Se non si ha paura di rovinare con bytecode, è possibile intercettare e patch di COMPARE_OP
con argomento 8 ("is")
di chiamare la vostra funzione di hook su oggetti a confronto. Guardate dis
documentazione del modulo per l'avvio in.
E non dimenticate di intercettare __builtin__.id()
anche se qualcuno farà id(a) == id(b)
invece di a is b
.
è non riesce a confrontare una variabile stringa al valore di stringa e due variabili stringa quando la stringa inizia con '-'. La mia versione di Python è 2.6.6
>>> s = '-hi'
>>> s is '-hi'
False
>>> s = '-hi'
>>> k = '-hi'
>>> s is k
False
>>> '-hi' is '-hi'
True
'è' a confronto identità di un oggetto mentre == confronta i valori.
Esempio:
a=[1,2]
b=[1,2]
#a==b returns True
#a is b returns False
p=q=[1,2]
#p==q returns True
#p is q returns True
Non è possibile sovraccaricare l'operatore is
. Che cosa si vuole di sovraccarico è l'operatore ==
. Questo può essere fatto attraverso la definizione di un metodo __eq__
nella classe.
Si sta utilizzando il confronto di identità. == è probabilmente quello che si vuole. L'eccezione a questo è quando si vuole essere verificare se un elemento e l'altro sono l'esatto stesso oggetto e nella stessa posizione di memoria. Nei tuoi esempi, della voce non sono gli stessi, dal momento che uno è di tipo diverso (my_string) rispetto agli altri (stringa). Inoltre, non c'è alcuna cosa come someclass.__is__
in python (a meno che, naturalmente, si è messo lì da soli). Se ci fosse, confronto di oggetti con è non sarebbe affidabile semplicemente confrontare le locazioni di memoria.
Quando ho incontrato il è parola chiave, mi ha confuso pure. Avrei pensato che è e == non erano diverse. Hanno prodotto la stessa uscita dall'interprete su molti oggetti. Questo tipo di ipotesi è in realtà esattamente ciò che è ... è per. E 'il pitone equivalente "Ehi, non confondono questi due oggetti. Sono diversi.", Che è essenzialmente quello che [chi è stato che mi ha raddrizzato] ha detto. Formulata in modo molto diverso, ma un punto == l'altro punto.
il per alcuni esempi utili e del testo per aiutare con le differenze a volte confuse visitare un documento dal di python.org host di posta scritto da "Danny Yoo "
o, se questo è in linea, utilizzare il non quotate pastebin ho fatto di esso del corpo.
nel caso in cui, in alcuni 20 o giù di Luna Blu (Luna Blu sono un vero e proprio evento), sono entrambi giù, io cito gli esempi di codice
###
>>> my_name = "danny"
>>> your_name = "ian"
>>> my_name == your_name
0 #or False
###
###
>>> my_name[1:3] == your_name[1:3]
1 #or True
###
###
>>> my_name[1:3] is your_name[1:3]
0
###
errori di asserzione può facilmente sorgere con è parola chiave durante il confronto oggetti. Ad esempio, gli oggetti a e b potrebbe contenere lo stesso valore e la stessa memoria indirizzo quota. Quindi, facendo un
>>> a == b
sta per valutare fino a
True
Ma se
>>> a is b
restituisce
False
Probabilmente si dovrebbe verificare
>>> type(a)
e
>>> type(b)
Questi potrebbe essere differente e una ragione per il fallimento.