2009-07-12 77 views
7

我不这么认为,但我想我会问,以防万一。例如,在一个封装中int类用途:python是否有转换运算符?

i = IntContainer(3) 
i + 5 

而且我不是在这个中断例子有兴趣,我一直在寻找的东西干净,一般情况下,不重写每一个int和字符串的方法。

谢谢,孙强。这正是我想要的。我没有意识到你可以继承这些不可变类型(来自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() 

回答

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 
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]: 
+1

不是。我正在寻找类似C++转换运算符的东西,它智能地用容器对象替换表达式中包含的任何东西。 – Alex 2009-07-12 23:06:28

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 
3

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

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

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__