这两天有一个特殊需求,在一个Python class上实现一个method,可以被当作Class method调用,也可以被当作Instance的Method调用。看起来不是很Pythonic,一个函数有两个不同的行为,不过在特殊情况下确实很实用。
尝试对性能进行了一下优化,并没有用到太复杂的优化方法,所以只是相对性能可以接受。调用消耗大概是普通调用的一倍。
from functools import wraps class hybridmethod(object): """ High performance hybrid function wrapper """ __slot__ = ['context', 'method', 'clsmethod'] def __init__(self, func): self.clsmethod = self.method = wraps(func)(lambda *a, **kw: func(self.context, *a, **kw)) def classmethod(self, func): """ Function to call when calling with class """ self.clsmethod = wraps(func)(lambda *a, **kw: func(self.context, *a, **kw)) return self def __get__(self, instance, cls): if instance is None: self.context = cls return self.clsmethod self.context = instance return self.method
自己用到的场景:
class Model(object): @hybridmethod def from_dict(self, dict_): """ Inflate the instance with dict """ for k, v in dict_.items(): setattr(self, k, v) return self @from_dict.classmethod def from_dict(cls, dict_): """ Inflate the instance with dict """ instance = cls() for k, v in dict_.items(): setattr(instance, k, v) return instance