Home > Software engineering >  Set property on a function object
Set property on a function object

Time:01-05

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.

  • Related