hurrytospring hurrytospring - 27 days ago 12
Python Question

How to set attributes of a function when defining this function?

We know that one can set attributes of a function like this:

def foo():
pass
foo.__setattr__("nameattr","myname")


Now, I'd like to set it like this:

def foo():
#self.__setattr__("nameattr","myname")
pass


Is there any solution?

Answer

You can just put the assignment inside the body of the function:

def foo():
    foo.nameattr = value

Or:

def foo():
    setattr(foo, "nameattr", value)

There is no need to explicitly call __setattr__.

Note however that this will set the attribute everytime you call the function, moreover you must call the function for this to work:

>>> a = 1
>>> def foo():
...     global a
...     foo.a = a
... 
>>> foo.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'a'
>>> foo()
>>> foo.a
1
>>> a = 2
>>> foo.a
1
>>> foo()
>>> foo.a
2

As you can see the attribute is not set if you don't call the function before accessing it. Moreover at everycall the value could change.

If you want to just set the attribute once you could use a decorator. It would be nice to be able to just use partial with setattr, but unfortunately setattr uses positional-only arguments. But we can write our own wrapper:

from functools import partial

def set_attribute(object, name, value):
    setattr(object, name, value)

@partial(set_attribute, name="a", value=1)
def foo():
    pass

print(foo.a)  # -> 1
Comments