Is it possible to assign property on a function object the similar way we assign it on class instances. My desired behaviour is like this
def prop():
print("I am a property")
def my_func():
print("Just a function call")
my_func.prop = prop
my_func.prop # prints 'I am a property'
I am able to invoke it as a function call my_func.prop()
, but is there a way to override __getattribute__
or something to achieve this result?
I have tried attaching it on a class
setattr(my_func.__class__, "prop", property(prop))
but definitely that's not the way
TypeError: cannot set 'prop' attribute of immutable type 'function'
CodePudding user response:
Limitations
So basically Python does not allow to do the described thing as
a) it is not possible to create your own "function" class Base class "FunctionType" is marked final and cannot be subclassed
import types
class F(types.FunctionType):
pass
or
base = type(lambda: ...)
class F(base):
pass
because TypeError: type 'function' is not an acceptable base type
b) it is not possible to modify existing built-in function
type
TypeError: cannot set 'prop' attribute of immutable type 'function'
Possible solution
Create your own Callable
class which would be a wrapper around your function
import typing
class MyFunc:
def __init__(self, func: typing.Callable):
self.f = func
def __call__(self, *args, **kwargs):
return self.f(*args, **kwargs)
and then assign property as you would on any other class
def prop(self):
print(f"I am a property of {self}")
@MyFunc
def my_func():
print("Just a function call")
setattr(my_func.__class__, "prop", property(prop))
my_func.prop
Example above is just for my question with dynamic assignment, you probably would you just @property
decorator on a method within class definition.