1

First of all I'm new to python so this is kinda confusing to me. I come from c++ background and there is nothing similar to this. I tried to google it but I don't even know how to call it.

I found this code where there seems to be some sort of variable bound to the function name like an object or something and I don't understand what it is and how it works and how is supposed to be used.

def foo():
    foo.counter+=1
foo.counter=0
foo()
print(foo.counter)

Now if I remove the foo. prefix, the program stops working.

However, if I add global declaration, it works again:

def foo():
    global counter
    counter+=1
counter=0
foo()
print(counter)

So my question is what exactly is that foo. prefix and what does it do ?

con
  • 11
  • 2

2 Answers2

1

In python nearly everything is an object. Even functions. You can get all Attributes of an object with:

>>> dir(foo)
[ ..., '__str__', '__subclasshook__', 'counter']

This means you added an extra Attribute to the function. This Attribute now can be manipulated and edited like any other Attribute of an object. Because the function is only created once there is only one object of foo. Because of this it is the same as using no foo and global.

Uli Sotschok
  • 1,206
  • 1
  • 9
  • 19
  • The annoying thing is that native C stuff are often not objects and don't support adding attributes. – LtWorf Aug 21 '19 at 07:29
  • Can you give me an example of native c stuff? – Uli Sotschok Aug 21 '19 at 07:30
  • AttributeError: 'list' object has no attribute 'i' – LtWorf Aug 21 '19 at 07:39
  • 1
    @LtWorf It's actually good. Imagine some code adding and removing arbitrary attributes to/from built-in types. That would be a nightmare to debug. – DeepSpace Aug 21 '19 at 07:46
  • 1
    If someone is curious why it is not possible to set Attributes to builtin types, it is because they have no `__dict__` Attribute. [SO Answer](https://stackoverflow.com/a/21320086/8411228) – Uli Sotschok Aug 21 '19 at 07:50
  • @DeepSpace then one would just use java and type safety. I think it's confusing that in python you can or can't do that depending on if your object is implemented in python or in C. – LtWorf Aug 21 '19 at 10:33
  • @LtWorf It's not confusing more than any other concept in any other programming language. You also can subtract integers and not strings. Why is that not confusing? – DeepSpace Aug 21 '19 at 10:35
  • There is no immediate concept of what subracting string means, this is way more intricate and has to do with saving memory. – LtWorf Aug 21 '19 at 13:05
0

Python functions are first-class citizens. This means they are objects as much as any other object is. A function can have attributes and even other functions.

For example every function has a built-in __name__ attribute:

def foo(x):
    print(x)

print(foo.__name__)

Outputs

foo

You can see all attributes an object has by using dir:

print(dir(foo))

Outputs

['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__',
 '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
 '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__',
 '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__',
 '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
DeepSpace
  • 78,697
  • 11
  • 109
  • 154