为类运行初始化程序

wil*_*ill 1 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
Run Code Online (Sandbox Code Playgroud)

但是,我希望这适用于所有对象,所以我可以只有一个类.这样我就可以让对象的行为与底层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
Run Code Online (Sandbox Code Playgroud)

但现在我收到了错误:

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

如果我看一下dir(self),它似乎没有为该类运行初始化器value.

是否有可能做到这一点?

我知道我可以为不同的类型制作一些不同的类,但我宁愿只有一个,只是让它是通用的.

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

Ale*_*lli 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
Run Code Online (Sandbox Code Playgroud)

发出的

15 The maximum memory we can use
[1, 2, 3] A useful list
Run Code Online (Sandbox Code Playgroud)

核心思想是将类包装成工厂函数 - 一种"额外的间接性",可以帮助您实现理想的结果.

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

其次,我还没有验证所有特殊方法在一个Setting包装的"原始类型" 上表现得如何(对于所有感兴趣的"原始类型",可变的和不可变的) - 随意它看起来应该可以工作,但除了彻底的单元测试可以让你有信心! - )