2012-10-06 11 views
6

Ho bisogno di una classe che è un numero intero il cui valore può essere modificato dopo che l'oggetto è stato creato. Ho bisogno di questa classe per definire una dimensione che viene specificata per la prima volta in millimetri. Più tardi, quando viene creata l'interfaccia utente, ottengo un fattore dal contesto del dispositivo che converte i millimetri in pixel. Questo fattore dovrebbe cambiare il valore millimetrico del mio oggetto su un valore di pixel.Oggetto intero il cui valore può essere modificato dopo la definizione?

Ho provato a sottoclasse int (vedi increment int object), ma int è immutabile, quindi non posso cambiare il suo valore.

class UiSize(int): 
    def __new__(cls, value=0): 
     i = int.__new__(cls, value) 
     i._orig_value = value 
     return i 

    def set_px_per_mm(self, px_per_mm): 
     pixel_value = int(round(self._orig_value * px_per_mm)) 
     print "pixel_value", pixel_value 
     # how to set the new pixel_value to the object's value ? 

s = UiSize(500) 
s.set_px_per_mm(300.0/500.0) 
print "1px + 500mm =", 1 + s, "px" # the result should be 301 pixels 

La risposta in increment int object era di costruire il mio classe con tutti i metodi del Int. Così ho provato questo:

class UiSize2(object): 
    def __init__(self, value=0): 
     self._int_value = int(value) 

    def __add__(self, other): 
     return self._int_value.__add__(other) 

    def set_px_per_mm(self, px_per_mm): 
     self._int_value = int(round(self._int_value * px_per_mm)) 

s = UiSize2(500) 
s.set_px_per_mm(300.0/500.0) 
print "500mm + 1 =", s + 1, "px" 

mi funziona per 's + 1', ma per '1 + s' ho un TypeError:

>>> print "1 + 500mm =", 1 + s, "px" 
TypeError: unsupported operand type(s) for +: 'int' and 'UiSize2' 

risposta

6

È necessario definire il metodo magico __radd__ (" aggiungi ") per controllare il comportamento quando il tuo tipo personalizzato è sul lato destro di un'aggiunta. Dovrai fare lo stesso per __rmul__, __rsub__, ecc. Per dare le versioni a destra di tutte le operazioni.

1

Utilizzando il magnitude package, si potrebbe gestire la conversione di unità in questo modo:

import magnitude 
mg = magnitude.mg 
new_mag = magnitude.new_mag 

s = mg(500, 'mm') # s is 500mm 

# Define a pixel unit; 300 px = 500 mm 
new_mag('px', mg(500.0/300.0, 'mm')) 

p = mg(1, 'px')  # p is 1 px 

print('500mm + 1px = {u}'.format(u = (s + p).ounit('px'))) 
# 500mm + 1px = 301.0000 px 
print('500mm + 1px = {u}'.format(u = (s + p).ounit('mm')))  
# 500mm + 1px = 501.6667 mm 
Problemi correlati