我不确定这个问题的好标题是什么,所以我会解释我想做什么。
我想要一个类,可以通过某种方式实例化:
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
属性,它将被覆盖,我打算仅将其用于原语,这是它首先出现问题的原因之一因为我不能只添加属性。)
答案 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