我不太确定这个问题的好标题是什么,所以我会解释我想做什么.
我想要一个类,可以通过某种方式实例化:
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
属性,它将被覆盖,我打算只使用这个原语,这是它首先出现问题的原因之一,因为我不能只添加属性.)
这是我认为你想要完成的概念验证:
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
包装的"原始类型" 上表现得如何(对于所有感兴趣的"原始类型",可变的和不可变的) - 随意它看起来应该可以工作,但除了彻底的单元测试可以让你有信心! - )