This snippet defines a decorator @mixedmethod similar to @classmethod, which allows the method to access the calling instance when it exists. The decorated functions have two implicit arguments self, cls, the former having a None value when there is no instance in the call.
Using python's descriptor protocol, the implementation of @mixedmethod needs no more than 5 lines of code !
@mixedmethod mixes class- and instance- method into one.
#!/usr/bin/env python
# -*-coding: utf8-*-
# Compatibility: python 2 and py3k
# Title: mixedmethod.py
# Author: Gribouillis
# Created: 2012-01-13 12:10:17.722112 (isoformat date)
# License: Public Domain
# Use this code freely.
from __future__ import print_function
from functools import partial
import sys
"""This module implements a mixedmethod() decorator for class definitions.
"""
version_info = (0, 1)
version = ".".join(map(str, version_info))
class mixedmethod(object):
"""This decorator mutates a function defined in a class into a 'mixed' class and instance method.
Usage:
class Spam:
@mixedmethod
def egg(self, cls, *args, **kwargs):
if self is None:
pass # executed if egg was called as a class method (eg. Spam.egg())
else:
pass # executed if egg was called as an instance method (eg. instance.egg())
The decorated methods need 2 implicit arguments: self and cls, the former being None when
there is no instance in the call. This follows the same rule as __get__ methods in python's
descriptor protocol.
"""
def __init__(self, func):
self.func = func
def __get__(self, instance, cls):
return partial(self.func, instance, cls)
if __name__ == '__main__':
class Spam(object):
@mixedmethod
def ham(self, cls, *args):
if self is None:
print("Spam.ham() was called as a class method with {0}.".format((self, cls)+ args))
else:
print("Spam.ham() was called as an instance method with {0}.".format((self, cls) + args))
def __repr__(self):
return '<Spam instance>'
egg = Spam()
egg.ham(5)
Spam.ham(5)
""" my output -->
Spam.ham() was called as an instance method with (<Spam instance>, <class '__main__.Spam'>, 5).
Spam.ham() was called as a class method with (None, <class '__main__.Spam'>, 5).
"""
TrustyTony 888 pyMod Team Colleague Featured Poster
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.