Domanda

Io uso spesso l'interprete Python per fare calcoli numerici rapidi e vorrei tutti i risultati numerici da stampare automaticamente utilizzando, per esempio, la notazione esponenziale. C'è un modo per impostare questo per l'intera sessione?

Per esempio, io voglio:

>>> 1.e12
1.0e+12

non

>>> 1.e12
1000000000000.0
È stato utile?

Soluzione

Creare uno script Python chiamato quello che vuoi (mystartup.py diciamo) e quindi impostare un ambiente PYTHONSTARTUP variabile al percorso di questo script. Python quindi caricare questo script all'avvio di una sessione interattiva (ma non quando l'esecuzione di script). In questo script, definire una funzione simile a questo:

def _(v):
    if type(v) == type(0.0):
        print "%e" % v
    else:
        print v

Poi, in una sessione interattiva:

C:\temp>set PYTHONSTARTUP=mystartup.py

C:\temp>python
ActivePython 2.5.2.2 (ActiveState Software Inc.) based on
Python 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> _(1e12)
1.000000e+012
>>> _(14)
14
>>> _(14.0)
1.400000e+001
>>>

Naturalmente, è possibile definire la funzione di essere chiamato whaetver che si desidera e di lavorare esattamente come vuoi.

Anche meglio di questa potrebbe essere quella di utilizzare IPython . E 'grande, ed è possibile impostare il numero di formattazione come si desidera utilizzando result_display.when_type(some_type)(my_print_func) (si veda il sito IPython oppure cerca altri dettagli su come usare questo).

Altri suggerimenti

Hm ... Non è una soluzione 100%, ma questo sono venuti in mente ...

Come sulla definizione di una sottoclasse di galleggiante che avrebbe un metodo __str__ sovrascritto (per stampare con la notazione exp). E poi si dovrebbe avvolgere tutte le espressioni con la costruzione oggetto di questa classe). Sarebbe un po 'più breve rispetto alla soluzione di Dave, si potrebbe definire la classe di una volta e poi scrivere qualcosa come:

>>> F(1.e12)
1.0e+12
>>> F(3.)
3.0e+0
>>> F(1.+2.+3.+4.)
1.0e+1
...

Come sapete è possibile utilizzare l'operatore % o str.format per stringhe di formato:

Ad esempio:

>>> "%e" % 1.e12
'1.000000e+12'

Mi chiedevo se si potesse la classe incorporata float per cambiare il formattazione ma sembra che Python non ti consente di:

>>> 1.e12.__class__.__repr__ = lambda x: "%e" % x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'float'

Quindi, l'unica altra cosa che posso pensare è quello di scrivere il proprio oggetto simile a file che cattura l'uscita, riformatta e lo invia sullo standard output. Farebbe quindi ridirezionare l'output standard dell'interprete a questo oggetto:

sys.stdout = my_formatting_object

Sulla suggerimento di Dave Webb sopra. Ovviamente si può impostare la precisione, se ti piace ( "% .3e") e forse ignorare writelines se necessario.

import os
import sys

class ExpFloatFileObject:
    def write(self, s):
        try:
            s = "%e"%float(s)
        except ValueError:
            pass
        sys.__stdout__.write(s)

    def __getattr__(self, name):
        return getattr(sys.__stdout__, name)

sys.stdout = ExpFloatFileObject()  

e l'uso di:

>>> 14000    
1.400000e+04  
>>> "text"
'text'

Quando si utilizza IPython / Jupyter-console, la "magia" di comando %precision %e cambierà la visualizzazione dei carri prime in notazione esponenziale. https://ipython.readthedocs.io/en/stable/ interattivo / magics.html # magic-precisione

Per un maggiore controllo della formattazione, un formattatore può essere registrato:

excited_floats = lambda val: "{:e}!!!".format(val)
console_formatter = get_ipython().display_formatter.formatters['text/plain']
console_formatter.for_type(float, lambda val, p, c: p.text(excited_floats(val)))

https : //ipython.readthedocs.io/en/stable/api/generated/IPython.core.formatters.html#IPython.core.formatters.PlainTextFormatter

Ci scusiamo per necroposting, ma questo argomento si presenta nelle ricerche Google Related e credo che una risposta soddisfacente manca qui.

Credo che la strada giusta è quella di utilizzare sys.displayhook . Ad esempio, è possibile aggiungere il codice come questo nel file PYTHONSTARTUP:

import builtins
import sys
import numbers


__orig_hook = sys.displayhook

def __displayhook(value):
    if isinstance(value, numbers.Number) and value >= 1e5:
        builtins._ = value
        print("{:e}".format(value))
    else:
        __orig_hook(value)

sys.displayhook = __displayhook

Questo mostrerà i valori abbastanza grande utilizzando la sintassi exp. Sentitevi liberi di modificare la soglia, come si vede in forma.

In alternativa si può avere la risposta stampato in entrambi i formati per grandi numeri:

def __displayhook(value):
    __orig_hook(value)
    if isinstance(value, numbers.Number) and value >= 1e5:
        print("{:e}".format(value))

In alternativa, è possibile definire se stessi un'altra variabile risposta oltre al _ predefinito, ad esempio __ (quali la creatività, lo so):

builtins.__ = None
__orig_hook = sys.displayhook

def __displayhook(value):
    if isinstance(value, numbers.Number):
        builtins.__ = "{:e}".format(value)
    __orig_hook(value)

sys.displayhook = __displayhook

... e quindi visualizzare la risposta exp-formattato digitando semplicemente __.

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