我在使用内置类型float
的派生类编写简单的单元转换器时遇到了一些困难。你知道吗
尝试1:
我尝试返回实例的新副本,而不是change the state of it
。然而,我无法做到这一点。
模式2
我试图更改self
的值,但它破坏了一个属性baseunit
,因此AttributeError
被提升。
另一件事是我真正想知道的是如何实现代数而不丢失类类型,例如a = Unit(km/s, 1) * 10
将Unit的实例返回为print a # 10 km/s
,而不是float 10.0
。所以我可以使用a.to('m/s')
进一步转换它,然后print a # 1e4 m/s
谢谢你我先走了!你知道吗
我按照你的建议修改了我的代码,正确使用了new。 它部分工作,因为我可以获得类Unit的转换实例并将其传递给一个变量。这就足够了。但是,是否有一种方法可以在站点上进行更改,即让返回的实例替换我原来的实例?你知道吗
再说一次,如果我尝试用另一种方式做生意,即
self /= self.conv[target]
self.baseunit = target
它抛出AttributeError,因为self
现在只是一个普通的浮点。我想我应该定义一个覆盖代数运算符的函数,这样baseunit
就不会丢失。但是怎么做呢?你知道吗
代码:
from __future__ import division
import numpy as np
class Unit(float):
"""provide a simple unit converter for a given quantity"""
baseconv = {'length': np.array((1e-10, 1e-6, 1e-2, 1., 1e3),
dtype=[('A', 'f'),
('um', 'f'),
('cm', 'f'),
('m', 'f'),
('km','f')]),
'speed': np.array((1e3, 1., 1e-2, 1e-10,),
dtype=[('km/s', 'f'),
('m/s', 'f'),
('cm/s', 'f'),
('A/s', 'f')]),
'1': np.array((1.,), dtype=[('1','f')])}
baseunit = None
def __new__(self, baseunit='1',num=1.):
return super(Unit,self).__new__(self, num)
def __init__(self, baseunit='1', num=1.):
"""set up base unit"""
self.baseunit = baseunit
for _key,_val in self.baseconv.items():
if baseunit in _val.dtype.names:
utype = _key
break
else:
raise TypeError('Unit not defined: {:s}'.format(baseunit))
self.conv = np.array(tuple(np.array(self.baseconv[utype].tolist())
/ self.baseconv[utype][baseunit]),
dtype=self.baseconv[utype].dtype)
def __str__(self,):
return '{:e} {:s}'.format(self, self.baseunit)
def to(self,target):
if target in self.conv.dtype.names:
return Unit(target, self / self.conv[target]) ! not work
else:
raise TypeError('Invalid converter: {:s}->{:s}'
.format(self.baseunit, target))
if __name__=='__main__':
u_test = Unit('km/s')
print u_test # 1.0000 km/s
u_conv = u_test.to('cm/s')
print u_conv # 1e5 cm/s
print u_test # 1.000 km/s
您需要
__new__
来创建(并返回)实例。不可变部分是num
,因此需要将其烘焙到实例化中。你知道吗初始化的剩余部分应该留给
__init__
。像这样的相关问题 更多 >
编程相关推荐