虽然你可以提出一种命名约定,但通过构建一个表示“距离”的对象,并具有以不同单位读写的属性,可能会更好地为你服务。例如:
class Distance(object):
def __init__(self):
self._inches = 0
@property
def inches(self):
return self._inches
@inches.setter
def inches(self, value):
self._inches = value
@property
def feet(self):
return self._inches/12
@feet.setter
def feet(self, value):
self._inches = value * 12
你甚至可以将其更加通用化,这样你就可以轻松地扩展新的转换。(注意:根据评论进行了编辑以进行备忘录)
from collections import defaultdict
class Distance(object):
_conversion_map = defaultdict(lambda: {'to' : None, 'from' : None})
def __init__(self, **kwargs):
self._memo = {}
if kwargs:
unit, value = kwargs.iteritems().next()
if unit == 'inches':
self.inches = value
else:
setattr(self, unit, value)
else:
self.inches = 0
def __getattr__(self, name):
if name in self._conversion_map:
try:
return self._memo[name]
except KeyError:
converter = self._conversion_map[name]['to']
if converter is None:
raise AttributeError
converted = converter(self.inches)
self._memo[name] = converted
return converted
else:
raise AttributeError
def __setattr__(self, name, value):
if name == '_memo':
super(Distance, self).__setattr__(name, value)
else:
self._memo = {}
if name == 'inches':
super(Distance, self).__setattr__(name, value)
if name in self._conversion_map:
converter = self._conversion_map[name]['from']
if converter is None:
raise AttributeError
self._memo[name] = value
self.inches = converter(value)
else:
raise AttributeError
@classmethod
def converter(cls, func):
direction, unit = func.__name__.split('_', 1)
cls._conversion_map[unit][direction] = func
return func
@Distance.converter
def to_feet(value):
return value / 12
@Distance.converter
def from_feet(value):
return value * 12
board_1_length = Distance(feet=2)
board_2_length = Distance(inches=14)
board_1_length.inches
board_2_length.feet
board_length = 24 # in inches
(几行之后)print(to_feet(board_length))
,或者FEET = 12; print(board_length*FEET)
。 - rlmsboard_length_inches
。保持简单。 - RemcoGerlich