整数对象,其值可以在定义后更改?

时间:2012-10-06 20:04:55

标签: python

我需要一个整数类,它的值可以在创建对象后更改。 我需要这个类来定义一个首先以毫米为单位指定的大小。稍后在创建用户界面时,我从设备上下文中获取一个因子,将毫米转换为像素。此因子应将我的对象的毫米值更改为像素值。

我试图将int子类化(参见increment int object),但int是不可变的,因此我无法更改其值。

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

increment int object中的答案是 用所有int的方法构建我自己的类。所以我尝试了这个:

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"

我为's + 1'工作,但对于'1 + s'我得到一个TypeError:

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

2 个答案:

答案 0 :(得分:6)

当您的自定义类型位于添加的右侧时,您需要定义__radd__魔术方法(“右侧添加”)来控制行为。您需要对__rmul____rsub__等执行相同的操作,以提供所有操作的右侧版本。

答案 1 :(得分:1)

使用magnitude package,您可以像这样处理单位转换:

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