pythonfunctionpropertiesgetattrpython-descriptors

Set property on a function object


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'

Solution

  • 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.