指示方法既是类方法又是实例方法的装饰器
项目描述
Python有实例方法、类方法(@classmethod)和静态方法(@staticmethod)。但它没有明确的方式来调用类或其实例上的方法。有了combomethod,它就可以做到了。
from combomethod import combomethod class A(object): @combomethod def either(receiver, x, y): return x + y a = A() assert a.either(1, 3) == 4 assert A.either(1, 3) == 4
哇! 现在您的方法可以接受类或实例——您想用它调用哪一个都可以。
讨论
在某些情况下,您可以用@classmethod模拟@combomethod。例如,上面的代码中没有对类或实例的实际引用,它们都可以被指定为@classmethod,因为它们可以用类或实例调用。但是,这里有一个问题:类方法总是传递类到方法中,即使它们是用实例调用的。使用这种方法,您永远无法访问实例变量。哎!
或者,如果移除了它的接收器参数,这两个函数都可以被指定为 @staticmethod。但尽管这样,它们既可以从实例或类中调用,但在这两种情况下,都不会传递调用该方法的对象。永远无法访问类或实例变量。哎哟又疼了!
尽管 @classmethod 和 @staticmethod 很有用,但它们无法处理偶尔非常重要的边缘情况:你需要用类或实例调用,同时还需要真正访问调用对象。以下是一个需要这种方法的例子。
class Above(object): base = 10 def __init__(self, base=100): self.base = base @combomethod def above_base(receiver, x): return receiver.base + x a = Above() assert a.above_base(5) == 105 assert Above.above_base(5) == 15 aa = Above(12) assert aa.above_base(5) == 17 assert Above.above_base(5) == 15
当你需要用实例或类调用,并且你还在乎调用对象时,@combomethod 真是既酷又炫。
注意事项
本模块主要是对 Mike Axiak 的Stack Overflow 帖子中的洞察和代码的便捷打包、测试和文档化。感谢,Mike!
使用 pytest、pytest-cov、coverage 和 tox 进行自动多版本测试。使用 Travis-CI 进行持续集成测试。使用 pyroma 进行打包代码检查。
成功打包并测试了 Python 的所有晚期版本:2.6、2.7、3.3、3.4、3.5、3.6 和 3.7 预发布版,以及最新的 PyPy 和 PyPy3 构建。
查看 CHANGES.yml 获取完整的变更日志。
作者 Jonathan Eunice 或 @jeunice on Twitter 欢迎您的评论和建议。
安装
要安装或升级到最新版本
pip install -U combomethod
您可能需要在这些命令前加上 sudo 以授权安装。在不具有超级用户权限的环境中,您可能想使用 pip 的 --user 选项,只为单个用户安装,而不是系统范围。您可能还需要针对您的系统配置特定版本的 pip2 或 pip3 安装程序。在不适用于您所需特定 Python 实例的 pip 的情况下,这是一个有用的备选方案
python3.6 -m pip install -U combomethod