为类运行初始化程序

时间:2015-01-05 16:07:15

标签: python python-3.x

我不确定这个问题的好标题是什么,所以我会解释我想做什么。

我想要一个类,可以通过某种方式实例化:

class Setting(int):
  def __init__(self, value, description=None):
    super(Setting, self).__init__(value)
    self.description = description

max_memory = Setting(5, description="The maximum memory we can use")

print s + 5 # 10
print s.description # The maximum memory we can use

但是,我希望这对所有对象都有用,所以我可以只有一个班级。这样我就可以让对象的行为与基础value对象完全相同,但只是附加description属性。

我尝试将上述内容更改为:

class Setting(object):
  def __init__(self, value, description=None):
    type(value).__init__(value)
    self.description = description

s = Setting(5)

print s + 5
print s.description

但现在我收到了错误:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    print s + 5
TypeError: unsupported operand type(s) for +: 'Setting' and 'int'

如果我查看dir(self),它似乎没有运行value类的初始化程序。

是否可以这样做?

我知道我可以为不同的类型制作一些不同的类,但我只想拥有一个而且只是通用的。

(是的,我意识到,如果对象具有description属性,它将被覆盖,我打算仅将其用于原语,这是它首先出现问题的原因之一因为我不能只添加属性。)

3 个答案:

答案 0 :(得分:5)

这是我认为你想要完成的概念验证:

def Setting(value, description=None):
  class Internal(type(value)):
      def __new__(self, value, description=None):
          return type(value).__new__(Internal, value)
      def __init__(self, value, description=None):
          super(Internal, self).__init__(value)
          self.description = description
  return Internal(value, description)

s = Setting(5, description="The maximum memory we can use")

print s+10, s.description

v = Setting([1, 2], description="A useful list")

print v+[3], v.description

发出

15 The maximum memory we can use
[1, 2, 3] A useful list

核心思想是将课程包装成工厂功能 - 一种“额外的间接性”,可以帮助您实现理想的结果。

我称之为“概念证明”,首先,因为它非常浪费内存:每次调用Setting时都会出现一个新的类对象。工厂函数应该将dict作为注册表从type(value)到包含它的特定Internal类,在运行时填充它 - 一种典型的“memoization”成语,尽管这里是用来节省内存,而不是运行时间。

其次,我还没有验证所有特殊方法在Setting - 包装的“基本类型”上的行为(对于所有感兴趣的“原始类型”,都是可变的和不可变的 - 随便似乎应该可以工作,但只有彻底的单元测试才能让你有信心! - )

答案 1 :(得分:0)

对象的内置repr()是一个字符串。您可以使用repr库对其进行修改,但我不确定它是否可以是其他类型。 this SO question.

中还有一些其他详细信息/想法

答案 2 :(得分:0)

如果我理解正确,您希望类型/类的行为与其类型一样正常,并且还有一个&#39;描述&#39;领域。你怎么做的很奇怪 - 我相信声明

type(value).__init__(value)

没有任何效果,虽然我很困惑为什么python不会为此发出警告。当然,init中的 init 调用应保留给超类。

我会执行以下操作并使用s.value而不是s:

class Setting(object):
  def __init__(self, value, description=None):
    self.value = value
    self.description = description

s = Setting(5)

print s.value + 5
print s.description