Python Hybrid Method

这两天有一个特殊需求,在一个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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.