method that can be called from a class and also from an instance
Marc Aymerich
glicerinu at gmail.com
Thu Nov 22 11:33:12 EST 2012
On Thursday, November 22, 2012 4:51:30 PM UTC+1, Peter Otten wrote:
> Marc Aymerich wrote:
>
>
>
> > Hi,
>
> >
>
> > I want to create a method within a class that is able to accept either a
>
> > class or an instance.
>
> >
>
> > class MyClass(object):
>
> > @magic_decorator
>
> > def method(param):
>
> > # param can be MyClass (cls) or an instance of MyClass (self)
>
> >
>
> > so I can do something like:
>
> >
>
> > instance = MyClass()
>
> >
>
> > MyClass.method()
>
> > instance.method()
>
> >
>
> > I guess the way to go is implementing a custom decorator (@magic_decorator
>
> > in my example), but, how can I know if the method has been called from the
>
> > class o from an instance?
>
> >
>
> > Thank you very much!!
>
>
>
> Why would you overload a method that way?
Yep, it's an strange pattern sure it can be done in a better way but this is the best I can think on, the context is:
I'm developing a permission system which can give general permissions for a given class and also specific permissions for a given object.
class Node(object):
@role
def has_perm(instance, user)
if is_class(instance): then global perm for user...
else: then specific perm for user...
>
> $ cat class_or_inst.py
>
> import functools
>
>
>
> class desc(object):
>
> def __init__(self, f):
>
> self._f = f
>
> def __get__(self, inst=None, class_=None):
>
> if inst is not None:
>
> return functools.partial(self._f, self=inst)
>
> elif class_ is not None:
>
> return functools.partial(self._f, class_=class_)
>
> raise TypeError("nobody expects the Spanish inquisition")
>
>
>
>
>
>
>
> class A(object):
>
> @desc
>
> def f(self=None, class_=None):
>
> if self is not None:
>
> return "instance"
>
> elif class_ is not None:
>
> return "class"
>
> return "unknown"
>
> $ python -i class_or_inst.py
>
> >>> A.f()
>
> 'class'
>
> >>> A().f()
>
> 'instance'
>
> >>> A.__dict__["f"].__get__()
>
> Traceback (most recent call last):
>
> File "<stdin>", line 1, in <module>
>
> File "class_or_inst.py", line 11, in __get__
>
> raise TypeError("nobody expects the Spanish inquisition")
>
> TypeError: nobody expects the Spanish inquisition
you are a genius! I've implemented this on my code and it works as expected ! Thanks :D
More information about the Python-list
mailing list