Decorators
The decorators
module provides a decorator instance_or_classmethod
that allows methods to be called on either an instance of a class or the class itself without the need to define the method specifically as an instance method or a class method. This decorator creates a custom descriptor that decides how to handle the method call based on whether instance
is None
or not.
The instance_or_classmethod
function takes a decorated
function as an argument and returns a callable that acts depending on the context of its call. This function defines a nested __get__
function within it that overrides the special __get__
method, which is part of the descriptor protocol in Python. This __get__
method is used to determine how attributes of objects should be accessed.
If instance
is None
, which implies that the method is being called on the class, the __get__
method delegates the call to the __get__
method of classmethod
, effectively turning the called method into a class method at that moment. If instance
is not None
, suggesting that the method is called on an instance of the class, the __get__
method retrieves the function itself, allowing it to behave as an instance method.
This dynamic behavior adds flexibility to class design, especially when a method needs to behave differently depending on whether it is called by an instance or the class itself. It's implemented by creating a custom class type dynamically with the type
function and then setting its __get__
method to the one defined locally, applied to the decorated
method. The module relies on Python's advanced features such as the descriptor protocol, the classmethod
built-in decorator, and type creation on the fly with type()
.
instance_or_classmethod(decorated)
Transforms a function into a method that can behave either as a classmethod or an instance method. The function dynamically determines whether it should behave as a classmethod or an instance method upon being accessed. It modifies the 'get' method of a new type, based on the 'classmethod' type, to change its behavior according to whether it is called from an instance or the class itself.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
decorated |
Callable[P, R]
|
The function that is to be converted into a dual-method. This function should be capable of handling both classmethod and instance method calls. |
required |
Returns:
Type | Description |
---|---|
Callable[P, R]
|
Callable[P, R]: A callable object that can behave either as a classmethod or an instance method depending on how it is accessed. |
Raises:
Source code in stateforward/model/decorators.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|