为所有操作模拟 class 实例的一个属性
Emulate one attribute of class instance for all operations
我希望我的 class 的实例始终被视为它的属性之一,除非特别请求其他属性。例如,假设我的 class 是:
class Value:
def __init__(self, value, description):
self.value = value
self.description = description
这样 value
是一个浮点数,description
是一个字符串。现在,我希望 始终 的操作将 Value
的实例视为 Instance.value
,除非明确要求 Instance.description
。
我知道有两种解决方案。第一种是通过以下方式在 class 中实现数值模拟:
def __add__(self, other):
return self.value + other
每一个可能的数值运算。然而,这似乎过于麻烦——如果有人想使用一个 Value 实例来乘以一个列表怎么办,错误消息又如何,所有其他在 class 实例而不是基本 float 上操作的方法都可能出错?我真的必须为每个可能的操作案例引入 class 方法吗?
第二种解决方案是按以下方式重新定义事物:
class Value(float):
pass
value1 = Value(8.0)
value1.description = 'The first value'
value2 = Value(16.3)
value2.description = 'The second value'
...
...
现在,实例只是浮点值,描述是硬编码的。但这看起来也很麻烦,而且令人难以置信地不 Pythonic。
我是否错过了一个非常简单的方法?或者我可以轻弹一下某个地方的某种布尔标志?似乎经常需要 Python 有办法。
"simple solution" 是您的第二个答案 - 子类化您尝试充当的任何值。您仍然可以覆盖 __init__
并添加您需要的任何实体(尽管您还必须覆盖 __new__
- 请参阅 ):
class Value(float):
def __new__(self, value, description=''):
return float.__new__(self, value)
def __init__(self, value, description=''):
# let the superclass construct itself
float.__init__(value)
# give self a description
self.description = description
value1 = Value(8.0, 'the first value')
value2 = Value(16.3, 'the second value')
print(value1 + value2) # 24.3
print(value1 * value2) # 130.4
print(value1.description) # the first value
print(value2.description) # the second value
这也与您的第一个可能的解决方案基本相同,除了 float
已经 已经 定义了所有算术运算符,而您只是继承了它。这里的缺点是浮点数是不可变的,因此在创建对象后不能更改值。
也可以创建一个装饰器来执行此操作,但这会复杂得多。
我希望我的 class 的实例始终被视为它的属性之一,除非特别请求其他属性。例如,假设我的 class 是:
class Value:
def __init__(self, value, description):
self.value = value
self.description = description
这样 value
是一个浮点数,description
是一个字符串。现在,我希望 始终 的操作将 Value
的实例视为 Instance.value
,除非明确要求 Instance.description
。
我知道有两种解决方案。第一种是通过以下方式在 class 中实现数值模拟:
def __add__(self, other):
return self.value + other
每一个可能的数值运算。然而,这似乎过于麻烦——如果有人想使用一个 Value 实例来乘以一个列表怎么办,错误消息又如何,所有其他在 class 实例而不是基本 float 上操作的方法都可能出错?我真的必须为每个可能的操作案例引入 class 方法吗?
第二种解决方案是按以下方式重新定义事物:
class Value(float):
pass
value1 = Value(8.0)
value1.description = 'The first value'
value2 = Value(16.3)
value2.description = 'The second value'
...
...
现在,实例只是浮点值,描述是硬编码的。但这看起来也很麻烦,而且令人难以置信地不 Pythonic。
我是否错过了一个非常简单的方法?或者我可以轻弹一下某个地方的某种布尔标志?似乎经常需要 Python 有办法。
"simple solution" 是您的第二个答案 - 子类化您尝试充当的任何值。您仍然可以覆盖 __init__
并添加您需要的任何实体(尽管您还必须覆盖 __new__
- 请参阅
class Value(float):
def __new__(self, value, description=''):
return float.__new__(self, value)
def __init__(self, value, description=''):
# let the superclass construct itself
float.__init__(value)
# give self a description
self.description = description
value1 = Value(8.0, 'the first value')
value2 = Value(16.3, 'the second value')
print(value1 + value2) # 24.3
print(value1 * value2) # 130.4
print(value1.description) # the first value
print(value2.description) # the second value
这也与您的第一个可能的解决方案基本相同,除了 float
已经 已经 定义了所有算术运算符,而您只是继承了它。这里的缺点是浮点数是不可变的,因此在创建对象后不能更改值。
也可以创建一个装饰器来执行此操作,但这会复杂得多。