【问题标题】:Creating my own "integer" object in Python在 Python 中创建我自己的“整数”对象
【发布时间】:2018-06-23 06:23:03
【问题描述】:

基本上我希望能够做类似的事情:

a = Integer(1)
a += 1
print a

当然还有打印数字二作为结果。我需要创建哪些方法才能在我的 Integer 类中获得这种行为?

免责声明:我不打算将其用于“真实”,只是好奇。

【问题讨论】:

标签: python object


【解决方案1】:

这是一个简单且不完整的示例。看看__sub____div__等方法。

class Integer(object):
    def __init__(self, val=0):
        self._val = int(val)
    def __add__(self, val):
        if isinstance(val, Integer):
            return Integer(self._val + val._val)
        return self._val + val
    def __iadd__(self, val):
        self._val += val
        return self
    def __str__(self):
        return str(self._val)
    def __repr__(self):
        return 'Integer(%s)' % self._val

然后

n = Integer()
print n
m = Integer(7)
m+=5
print m

EDIT 修复了__repr__ 并添加了__iadd__。感谢@Keith 指出问题。 EDIT 修复了__add__ 以允许整数之间的加法。

【讨论】:

  • 这个例子误用了__repr__。这旨在返回 eval() 的倒数,在这种情况下应该返回 Integer(val)。它也不维护类型:Python2> m = Integer(7) Python2> type(m) <class '__main__.Integer'> Python2> m+=5 Python2> type(m) <type 'int'>
  • 你应该继承自numbers.Number,而不是object;根据下面的ncoghlan回答。如果你想删除不需要的继承方法,这很容易。
【解决方案2】:

首先,快速查看emulating numeric types 上的参考手册中的文档。

(不要太拘泥于此 - 这只是为了让您熟悉 Python 中的算术运算基础方法)

然后请参阅numbers module 的文档,其中包括与模拟不同类型的数字最相关的所有抽象基类(例如,numbers.Integral 用于自定义整数)。

【讨论】:

    【解决方案3】:

    你可以使用operator overloading:

    class Integer:
    
      def __init__(self, value):
        self.value = value
    
      def __repr__(self):
        return str(self.value)
    
      def __add__(self, value):
        self.value += value
        return self
    
    a = Integer(2)
    print a
    
    a = a+3
    print a
    
    a += 4
    print a
    

    【讨论】:

      【解决方案4】:

      如果您想重载默认转换为字符串方法的运算符,您要查找的短语是“魔术方法”。这些是名为“__<name>__”的方法,python 在直接方法调用以外的情况下使用这些方法。您需要为您的类定义 __add____str__ 方法,以便分别使第 2 行和第 3 行工作。

      值得一提的是,如果你的新类型是左操作数,__add__ 方法将被调用,并且任何类型都可以作为它的参数传递。对于您的操作数是正确的情况,您还应该定义 __radd__ 方法。这适用于所有二元运算符。

      有关数字类型的更完整的魔法方法列表,请参阅Emulating Numeric Types

      【讨论】:

        【解决方案5】:

        我假设您希望您的 Integer 类是可变的。为了获得您的示例,这将起作用:

        class Integer(object):
            def __init__(self, num):
                self._val = num
        
            def __iadd__(self, other):
                self._val += int(other)
        
            def __str__(self):
                return str(self._val)
        

        【讨论】:

          【解决方案6】:
          class Integer(object):
          
              def __init__(self, value=0):
                  self._value = int(value)
          
              def __add__(self, other):
                  if isinstance(other, Integer):
                      return Integer(self._value + other._value)
                  return Integer(self._value + other)
          
              def __iadd__(self, other):
                  if isinstance(other, Integer):
                      self._value += other._value
                  else:
                      self._value += other
                  return self
          
              def __sub__(self, other):
                  if isinstance(other, Integer):
                      return Integer(self._value - other._value)
                  return Integer(self._value - other)
          
              def __isub__(self, other):
                  if isinstance(other, Integer):
                      self._value -= other._value
                  else:
                      self._value -= other
                  return self
          
              def __mul__(self, other):
                  if isinstance(other, Integer):
                      return Integer(self._value * other._value)
                  return Integer(self._value * other)
          
              def __div__(self, other):
                  if isinstance(other, Integer):
                      return Integer(self._value / other._value)
                  return Integer(self._value / other)
          
              def __str__(self):
                  return str(self._value)
          
              def __int__(self):
                  return self._value
          
              def __float__(self):
                  return float(self._value)
          
              def __repr__(self):
                  return 'Integer(%s)' % self._value
          

          【讨论】:

            【解决方案7】:

            试试这个:

            class Integer(int):
                def __init__(self, value):
                    self.value = value
                # Add extra stuff here.
            

            这将创建一个基于 int 的类,该类负责处理 __repr____iadd____isub__

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-09-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多