sometimes I have need to write class with static methods, however with possibility to initialized it and keep state (object)
sth like:
class A:
@classmethod
def method(cls_or_self):
# get reference to object when A().method() or to class when A.method()
code
what I have now is:
class A:
def method(self = None, *params): code
# or
def method2(self = None, **params): code
# but what I need is rather normal parameters, not optional and named args:
def method3(self_or_cls, a, b=1, c=2, *p, **kw): code
please do not write about differences between staticmethod and classmethod. I am interested if such decorator exists (in more or less standard libs) and moreover if above is suitable for PEP.
Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class. Static methods do not know about class state.
You can use class methods for any methods that are not bound to a specific instance but the class. In practice, you often use class methods for methods that create an instance of the class. When a method creates an instance of the class and returns it, the method is called a factory method.
Class methods don't need a class instance. They can't access the instance ( self ) but they have access to the class itself via cls . Static methods don't have access to cls or self . They work like regular functions but belong to the class's namespace.
Functions can be called only by its name, as it is defined independently. But methods can't be called by its name only, we need to invoke the class by a reference of that class in which it is defined, i.e. method is defined within a class and hence they are dependent on that class.
Functions and classmethod
objects act as descriptors; both return a wrapper that when called will in turn call the underlying function with an extra parameter. The only difference between how functions and classmethod
objects behave is in what that extra parameter is.
To create a hybrid of the two approaches, build your own descriptor decorator:
from functools import wraps
class hybridmethod(object):
def __init__(self, func):
self.func = func
def __get__(self, obj, cls):
context = obj if obj is not None else cls
@wraps(self.func)
def hybrid(*args, **kw):
return self.func(context, *args, **kw)
# optional, mimic methods some more
hybrid.__func__ = hybrid.im_func = self.func
hybrid.__self__ = hybrid.im_self = context
return hybrid
Here, we return a wrapper that'll use either the class or the instance as the first parameter, depending on what is available when the descriptor __get__
method is called.
Demo:
>>> class Foo(object):
... @hybridmethod
... def bar(cls_or_self):
... print 'Called with cls_or_self={!r}'.format(cls_or_self)
...
>>> Foo.bar()
Called with cls_or_self=<class '__main__.Foo'>
>>> Foo().bar()
Called with cls_or_self=<__main__.Foo object at 0x1043a4390>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With