python有转换运算符吗?

时间:2009-07-12 22:59:01

标签: python operators

我不这么认为,但我想我会问以防万一。例如,用于封装int:

的类
i = IntContainer(3)
i + 5

我不只是对这个int示例感兴趣,我一直在寻找干净和通用的东西,而不是覆盖每个int和string方法。

谢谢,孙强。这就是我想要的。我没有意识到你可以继承这些不可变类型(来自C ++)。

class IntContainer(int):
    def __init__(self,i):
        #do stuff here
        self.f = 4

    def MultiplyBy4(self):
        #some member function
        self *= self.f
        return self

print 3+IntContainer(3).MultiplyBy4()

5 个答案:

答案 0 :(得分:11)

这应该做你需要的:

class IntContainer(object):
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        # do some type checking on other
        return self.x + other

    def __radd__(self, other):
        # do some type checking on other
        return self.x + other

输出:

In [6]: IntContainer(3) + 6
Out[6]: 9

In [7]: 6 + IntContainer(3)
Out[7]: 9

有关详细信息,请在以下文档中搜索“radd”:

你会找到其他类似的方法来“正确添加”,“右减”等等。

这是覆盖相同运营商的另一个链接:

顺便说一下,Python确实有转换操作符:

但是,它们不会在你的例子中完成你需要的东西(基本上因为方法没有任何类型的参数注释,所以没有好的方法可以隐式地进行投射)。所以你可以这样做:

class IntContainer2(object):
    def __init__(self, x):
        self.x = x

    def __int__(self):
        return self.x


ic = IntContainer2(3)
print int(ic) + 6
print 6 + int(ic)

但这会失败:

print ic + 6  # error: no implicit coercion

答案 1 :(得分:3)

这是你需要的吗?

In [1]: class IntContainer(object):
   ...:     def __init__(self, val):
   ...:         self.val = val
   ...:     def __add__(self, val):
   ...:         return self.val + val
   ...:     def __radd__(self, val):
   ...:         return self.val + val
   ...:
   ...:

In [2]: i = IntContainer(3)

In [3]: i + 5
Out[3]: 8

In [4]:

答案 2 :(得分:3)

你不会像C ++那样得到转换运算符,因为Python没有这种强大的静态类型系统。唯一的自动转换运算符是处理默认数值的运算符(int / float);它们是用语言预定义的,不能更改。

类型“转换”通常由构造函数/工厂完成。然后,您可以重载__add__之类的标准方法,使其更像其他类。

答案 3 :(得分:3)

有时可能只是直接来自int的子类就足够了。然后__add____radd__不需要服装。

class IntContainer(int):
    pass
i = IntContainer(3)
print i + 5 # 8 
print 4 + i # 7

class StrContainer(str):
    pass
s = StrContainer(3)
print s + '5' # 35
print '4' + s # 43

答案 4 :(得分:0)

很抱歉晚了8.5年来参加聚会。 您可以从不可变(即int)派生。您无法定义__init__,因为已经创建了不可变项,并且无法修改(根据定义)。这是__new__派上用场的地方。

class IntContainer(int):
   def __new__ (cls, val):
      ival = int.__new__(cls, val)
      ival._rval = 'IntContainer(%d)' % ival
      return ival
   def __repr__ (self):
      return self._rval

In [1]: i = IntContainer(3)

In [2]: i
Out[2]: IntContainer(3)

In [3]: repr(i)
Out[3]: 'IntContainer(3)'

In [4]: str(i)
Out[4]: '3'

In [5]: i + 5
Out[5]: 8

In [6]: 4 + i
Out[6]: 7

In [7]: int(i)
Out[7]: 3

In [8]: float(i)
Out[8]: 3.0

现在,回答有关转换运算符的问题。您还可以定义__int____long____float__,以及__str__。要转换或转换为任意对象,您很可能需要修改其他对象以获得所需内容。您可以使用该其他对象的__new__方法。或者,如果已创建其他对象,请尝试使用__call__