假设我有面向性能的类型mylib.color.Hardware
,以及它的用户友好对应的mylib.color.RGB
和mylib.color.HSB
。当用户友好的颜色传递到库函数中时,它被转换成color.Hardware
。现在它是通过检查传递的参数的类型来实现的。但在将来我想接受和自动转换从任何类型,它提供了相应的转换功能。例如,实现其他lib.color.LAB'. 你知道吗
现在我在玩原型,像这样:
class somelib:
class A(object):
def __init__(self, value):
assert isinstance(value, int)
self._value = value
def get(self):
return self._value
class userlib:
class B(object):
def __init__(self, value):
self._value = value
def __toA(self):
try: value = int(self._value)
except: value = 0
return somelib.A(value)
__typecasts__ = {somelib.A: __toA}
def autocast(obj, cast_type):
if isinstance(obj, cast_type): return obj
try: casts = getattr(obj, '__typecasts__')
except AttributeError: raise TypeError, 'type cast protocol not implemented at all in', obj
try: fn = casts[cast_type]
except KeyError: raise TypeError, 'type cast to {0} not implemented in {1}'.format(cast_type, obj)
return fn(obj)
def printValueOfA(a):
a = autocast(a, somelib.A)
print 'value of a is', a.get()
printValueOfA(userlib.B(42.42)) # value of a is 42
printValueOfA(userlib.B('derp')) # value of a is 0
这是我的第二个原型,不那么麻烦,但更冗长:
# typecast.py
_casts = dict()
def registerTypeCast(from_type, to_type, cast_fn = None):
if cast_fn is None:
cast_fn = to_type
key = (from_type, to_type)
global _casts
_casts[key] = cast_fn
def typeCast(obj, to_type):
if isinstance(obj, to_type): return obj
from_type = type(obj)
key = (from_type, to_type)
fn = _casts.get(key)
if (fn is None) or (fn is NotImplemented):
raise TypeError, "type cast from {0} to {1} not provided".format(from_type, to_type)
return fn(obj)
# test.py
from typecast import *
registerTypeCast(int, str)
v = typeCast(42, str)
print "result:", type(v), repr(v)
问题。是否存在具有相同功能的库?(我不想重新发明方向盘,但我的google fu不会产生任何效果。)或者你可以建议更好的方法(也许更具python风格)?你知道吗
编辑:增加了第二个原型。你知道吗
您正在寻找一个组件体系结构和适应。Zope Component Architecture允许您注册接口和适配器;一个中央注册表,用于查找从一种类型到另一种类型的转换器。只要存在将值转换为目标类型的适配器,就可以将任何对象传递到API中。你知道吗
首先定义目标类型需要的接口:
然后,任何类都可以实现该接口(此类类的实例将提供该接口)。你知道吗
对于您的RGB类,然后注册一个适配器;如果您有一个
IRGB
接口,它会有所帮助,但不是必需的:现在您的API只需要将值“强制”到
IHardware
:就这样。如果
hardware
值直接提供IHardware
接口,则返回时保持不变。如果它是一个RGB
实例,则在注册表中找到一个适配器;适配器被创建(RGBtoHardwareAdapter(hardware)
被调用),并将像一个IHardware
对象一样工作。你知道吗也可以让适配器返回实际的
Hardware()
对象;上面的示例返回代理对象,但原理是相同的。你知道吗Python的Abstract Base Classes从另一个方向处理接口,即ducktyping。您可以测试给定的对象是否符合ABCs方法和属性。然而,它不提供适应性。你知道吗
相关问题 更多 >
编程相关推荐