我有一些代码,我想通过实例或类互换。 所有我将在代码做的是叫我希望这两个类和实例有(该方法的方法go()
在下面的例子)。
不幸的是,我不能创建一个常规方法的名称相同的类方法...请参见下面的例子。 我最初预计的第二次调用产生a
代替b
。
就如何实现这一目标的任何建议吗?
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
考虑重用classinstancemethod
从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))
你可以创建特制的自己的方法类型__get__()
方法。
在这种方法中,你可以做这样的事情:
class combimethod(object):
def __init__(self, func):
self._func = func
def classmethod(self, func):
self._classfunc = classmethod(func)
return self
def __get__(self, instance, owner):
if instance is None:
return self._classfunc.__get__(instance, owner)
else:
return self._func.__get__(instance, owner)
class A(object):
@combimethod
def go(self):
print "instance", self
@go.classmethod
def go(cls):
print "class", cls
a=A()
print "i:",
a.go()
print "c:",
A.go()
注:以上是不是很彻底的测试,但似乎工作。 然而,应该被看作是一种“解决方案 - 近伪码”,而不是作为一种解决方案。 它应该给你一个想法如何实现自己的目标。
如何是这样的:
import inspect
class A(object):
@staticmethod
def go(obj):
if inspect.isclass(obj):
print 'class'
else:
print 'instance'
A.go(int) # class
A.go(1) # instance
A.go(A) # class
A.go(A()) # instance
文章来源: Duck typing and class methods (or, how to use a method from both a class and an instance?)