鸭子类型和类方法(或者,如何同时使用类和实例中的方法?) [英] Duck typing and class methods (or, how to use a method from both a class and an instance?)

查看:87
本文介绍了鸭子类型和类方法(或者,如何同时使用类和实例中的方法?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码想要互换地传递实例或类.我在该代码中要做的就是调用一个我希望类和实例都具有的方法(在下面的示例中,方法go()).

I have some code which I would like to pass instances or classes interchangeably. All I will do in that code is to call a method that I expect both classes and instances to have (the method go() in the example below).

不幸的是,我无法使用与常规方法相同的名称来创建类方法.请参见下面的示例.我最初希望第二个调用产生一个a而不是一个b.

Unfortunately, I can't create a classmethod with the same name of a regular method... See example below. I initially expected the second call to produce an a instead of a b.

关于如何实现这一目标的任何建议?

Any advice on how to achieve this?

Type "help", "copyright", "credits" or "license" for more information.
>>> class A(object):
...     def go(self):
...             print "a"
...     @classmethod
...     def go(cls):
...             print "b"
... 
>>> a=A()
>>> a.go()
b
>>> A.go()
b

推荐答案

请考虑重用formencode中的classinstancemethod装饰器.

Consider reusing the classinstancemethod decorator from formencode.

https://bitbucket.org/formencode/official- formencode/src/06d52c5b33c9/formencode/declarative.py

class classinstancemethod(object):
    """
    Acts like a class method when called from a class, like an
    instance method when called by an instance.  The method should
    take two arguments, 'self' and 'cls'; one of these will be None
    depending on how the method was called.
    """

    def __init__(self, func):
        self.func = func

    def __get__(self, obj, type=None):
        return _methodwrapper(self.func, obj=obj, type=type)


class _methodwrapper(object):

    def __init__(self, func, obj, type):
        self.func = func
        self.obj = obj
        self.type = type

    def __call__(self, *args, **kw):
        assert 'self' not in kw and 'cls' not in kw, (
            "You cannot use 'self' or 'cls' arguments to a "
            "classinstancemethod")
        return self.func(*((self.obj, self.type) + args), **kw)

    def __repr__(self):
        if self.obj is None:
            return ('<bound class method %s.%s>'
                    % (self.type.__name__, self.func.func_name))
        else:
            return ('<bound method %s.%s of %r>'
                    % (self.type.__name__, self.func.func_name, self.obj))

这篇关于鸭子类型和类方法(或者,如何同时使用类和实例中的方法?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆