1

I am not sure exactly what this means or how it is used, but I came across this functionality when it comes to a function. I am able to dynamically add attributes to a function.

What is the use of this and how does it happen? I mean it's a function name after all, how can we add attributes to it dynamically?

def impossible():
    print "Adding a bool"

impossible.enabled = True 
# I was able to just do this. And this is a function, how does this add up?

print(impossible.enabled) # No attribute error. Output: True
7
  • It’s not a function name; it’s a function, and it’s like any other value. Any type can permit or forbid new attributes. Commented Apr 15, 2018 at 7:07
  • Does the same apply for a class as well? Commented Apr 15, 2018 at 7:09
  • The same which? =) Classes are also like any other values, and also are a type that permit new attributes, yes. Classes aren’t functions, though (try isinstance(SomeClass, type(some_function))). Commented Apr 15, 2018 at 7:11
  • Is there a way to print the definition of the function, in case i do that would i be able to see the new attribute appended to it? Commented Apr 15, 2018 at 7:12
  • There is, but an attribute on a function isn’t part of a function’s definition anyway. You can use dir(impossible) to see all the names of attributes on it. Commented Apr 15, 2018 at 7:12

3 Answers 3

3

in python functions are objects, they have all sorts of inner attributes and they can also have the __dict__ attribute, and like any other object anything in __dict__ is a variable of that object.you can see it if you print it before and after impossible.enabled

def impossible():
    print "Adding a bool"

print(impossible.__dict__) #  {}
impossible.enabled = True 
print(impossible.__dict__) #  {'enabled': True}

this doesn't change the function in any way since most of the time __dict__ is empty and holds no special value in a function. in fact its a bit useful since you could use this in a function to store static variables without cluttering your global names

Sign up to request clarification or add additional context in comments.

12 Comments

randomName = 'Jack' # Is this an object? ( As in randomName)
no strings, numbers, booleans and None are primitives not objects
@AntiMatterDynamite: This is Python. Yes, strings, numbers, booleans, and None are objects – they’re just immutable. (isinstance(True, object))
@Abhishek: It is an object. Every value in Python is an object.
So why can't we add attributes to a string object? Like randomName.Enabled = True
|
0

The name impossible points to an object that represents the function. You're setting a property on this object (which python allows you to do on all objects by default):

>>> def foo():
...   print("test")
...
>>> dir(foo)
['__call__', ..., 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
>>> foo.a = 'test'
>>> dir(foo)
['__call__', ..., 'a', ...]

Since this object implements __call__, it can be called as a function - you can implement your own class that defines __call__ and it'll also be allowed to be called as a function:

>>> class B:
...   def __call__(self, **kw):
...     print(kw)
...
>>> b = B()
>>> b()    
{}
>>> b(foo='bar')
{'foo': 'bar'}

If you create a new function, you can see that you haven't done anything to the definition of a function (its class), just the object that represents the original function:

>>> def bar():
...   print("ost")
...
>>> dir(bar)
['__call__', ..., 'func_closure', ...] 

This new object does not have a property named a, since you haven't set one on the object bar points to.

Comments

0

You can, for example, use a function attribute to implement a simple counter, like so:

def count():
    try:
        count.counter += 1
    except AttributeError:
        count.counter = 1
    return count.counter

Repeatedly calling "count()" yields: 1, 2, 3, ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.