Python 用于自动(可能是快速)用户类型转换的协议?
假设我有面向性能的类型Python 用于自动(可能是快速)用户类型转换的协议?,python,python-2.7,type-conversion,Python,Python 2.7,Type Conversion,假设我有面向性能的类型mylib.color.Hardware,以及它的用户友好对应类型mylib.color.RGB和mylib.color.HSB。当用户友好的颜色传递到库函数中时,它将转换为color.Hardware。现在,它是通过检查传递的参数的类型来实现的。但在将来,我想接受并自动转换任何类型,它提供了相应的转换功能。例如,实现“otherlib.color.LAB”的第三方库 现在我正在玩原型,类似这样的东西: class somelib: class A(object):
mylib.color.Hardware
,以及它的用户友好对应类型mylib.color.RGB
和mylib.color.HSB
。当用户友好的颜色传递到库函数中时,它将转换为color.Hardware
。现在,它是通过检查传递的参数的类型来实现的。但在将来,我想接受并自动转换任何类型,它提供了相应的转换功能。例如,实现“otherlib.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)
问题。是否存在具有相同功能的库?(我不想重新发明轮子,但我的谷歌fu不会产生任何效果。)或者你可以建议更好的(也许更像python)方法吗
编辑:添加了第二个原型。您正在寻找组件体系结构和适应性。允许您注册接口和适配器;查找从一种类型到另一种类型的转换器的中央注册表。只要存在将值转换为目标类型的适配器,就可以将任何对象传递到API中 首先定义目标类型需要的接口:
from zope.interface import Interface, Attribute
class IHardware(Interface):
"""A hardware colour"""
bar = Attribute("The bar value for the frobnar")
def foo():
"""Foo the bar for spam and eggs"""
然后,任何类都可以实现该接口(此类类的实例将提供该接口)
对于您的RGB类,然后注册一个适配器;如果您有IRGB
接口,则它会有所帮助,但不是必需的:
from zope.interface import implements
from zope.component import adapts
from zope.component import getGlobalSiteManager
class RGB(object):
def __init__(self, r, g, b):
self.r, self.g, self.b = r, g, b
class RGBtoHardwareAdapter(object):
implements(IHardware)
adapts(RGB)
def __init__(self, rgb_instance):
self._rgb = rgb_instance
self.bar = '{},{},{}'.format(rgb_instance.r, rgb_instance.g, rgb_instance.b)
def foo(self):
return self.bar + ' in rgb and spam and eggs'
gsm = getGlobalSiteManager()
gsm.registerAdapter(RGBtoHardwareAdapter)
现在,您的API只需要将您的值“强制”到IHardware
:
def some_api_call(hardware):
hardware = IHardware(hardware)
就这样。如果hardware
值直接提供IHardware
接口,则返回时将保持不变。如果是RGB
实例,则在注册表中找到适配器;适配器已创建(RGBtoHardwareAdapter(硬件)
已调用),其作用类似于IHardware
对象
您还可以让适配器返回实际的Hardware()
对象;上面的示例返回一个代理对象,但原理相同
Python的方法从不同的方向进行接口,即ducktyping。您可以测试给定对象是否符合ABCs方法和属性。但是,它不提供自适应功能。如果您愿意为每个类添加
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
属性,为什么不添加一个类似hardware\u color
的方法,返回color.hardware
对象?@JanneKarila,因为的确切类型将在“运行时”已知。我有两个后端。当mylib
初始化时,它会将一些自己的符号绑定到当前所选后端中的相应符号。哦,天哪,这太棒了。组件架构对我来说太过分了。我想它会很慢,但我需要每秒数千次的投射。另外,我还有第二个原型(刚刚添加到我的帖子中),我正在注册cast函数,但它更加轻量级。不管怎样,谢谢你们的回答,有趣的阅读。@ShadowsInRain:实际上,它是非常优化的。整个高流量网站都依赖于它的速度。但是从类型到转换函数/方法的映射也很好。@ShadowsInRain:FWIW,\uuu adaptes\uu
方法包含在;它可能比您想要的要正式一点,但并不慢。:-)哦,我怎么会忘记python模块可能是用C编写的呢^_^
def some_api_call(hardware):
hardware = IHardware(hardware)