2015-05-01 16 views
5

Come fa un int in pitone evitare essendo un oggetto ma tuttavia è uno:Python 2.7: Ints come oggetti

Se io il seguente:

>>> dir(10) 
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real'] 
>>> 10.__add__(20) 
    File "<stdin>", line 1 
    10.__add__(20) 
      ^
SyntaxError: invalid syntax 

Se digito 10. produce 10.0 mentre qualsiasi cosa come 10 .__ qualsiasi cosa __ produce un errore di sintassi. Ha senso dal momento che un float sarebbe considerato come 10.5 ma

  1. come viene raggiunto/implementato?
  2. come posso chiamare i metodi int su un int?

risposta

7

Il tokenizzatore Python è avido, cerca sempre di abbinare il segnalino più lungo possibile in qualsiasi posizione data; altrimenti potrebbe pensare che lo 10.e+123 sia lo stesso di (10).e + 123.

Nel caso di 10.__add__(20) vede i seguenti token:

>>> tokenize.tokenize(iter(['10.__add__(20)']).next) 
1,0-1,3:  NUMBER '10.' 
1,3-1,10:  NAME '__add__' 
1,10-1,11:  OP  '(' 
1,11-1,13:  NUMBER '20' 
1,13-1,14:  OP  ')' 
2,0-2,0:  ENDMARKER  '' 

cioè la . stato considerato una parte del numero letterale, ad esempio a float. Se si parenthesize il numero ((10).__add__(20)), si otterrà:

>>> tokenize.tokenize(iter(['(10).__add__(20)']).next) 
1,0-1,1:  OP  '(' 
1,1-1,3:  NUMBER '10' 
1,3-1,4:  OP  ')' 
1,4-1,5:  OP  '.' 
1,5-1,12:  NAME '__add__' 
1,12-1,13:  OP  '(' 
1,13-1,15:  NUMBER '20' 
1,15-1,16:  OP  ')' 
2,0-2,0:  ENDMARKER  '' 

Allo stesso modo, solo l'aggiunta di uno spazio tra il numero e il punto (10 .) avrebbe funzionato qui.

Qui lo . viene tokenizzato come operatore separato. Se una costante float farebbe, allora si potrebbe effettivamente digitare:

10..__add__(20) 

Si tratta di token come float letterale 10. seguita da un . seguito da identificatore __add__ e così via.


sciocco iter().next deve essere iter().__next__ su Python 3. Il tokenize.tokenize richiede un argomento che è funzione readline -come; quando chiamato, dovrebbe restituire una riga di input del programma.

2

Basta usare le parentesi attorno al numero:

(10).__add__(20) 
2

E 'una questione di lexing. Puoi racchiudere il numero tra parentesi per accedere ai membri, ad es. (10).__add__(20)

L'espressione 10.__add__(20) viene analizzata/ixata come (10.) __add__(20).

+0

Cosa fa la parentesi sul lato sinistro in questo caso? Valuta l'espressione in un oggetto int? – Har

+1

Immagino che si possa dire questo, ma lo si deve disambiguare da un float – ReyCharles

+0

'(10.) __add __ (20)' e '10 .__ add __ (20)' è lo stesso. – ReyCharles