Ex41 function vs attributes

What is the difference of function and attribute?
I have been running ex41 script to translate the OOP into English and English to OOP for several days now. My mistakes are fewer and need to look at phase drill above it les and less. However, I am constantly not getting these two correct.

foo.M(J)
"From foo, get the M function, and call it with parameters self, J."
    foo.K = Q
"From foo, get the K attribute, and set it to Q."

I put “get attribute” when it should be “get function” and vise versa. (unless i look at the chart.)
Whats confusing me is foo.M and foo.K parts look alike.
I have looked tough this forum and online all morning and have fell down a couple rabbit holes, none of which answer me.
I can memorize what to say when i see' = ' or ' () ' but i think I’m missing something I probably should have caught before.
Thanks for any help or direction to look.

From an abstract point of view one could say that a function that belongs to a class (often called a ‘method’) is a kind of attribute, too, because functions can be passed around like everything else.

The important distinction here is what you do with the attribute you’re looking up – and you’ve already spotted that: Functions are so called callables, which means that you can execute (‘call’) them – that’s what you do with the parentheses.

Here’s me defining a trivial function in the python shell:

>>> def twice(x): return 2 * x

Now twice without parentheses is just the name of the function:

>>> twice
<function twice at 0x000002287542A3A0>

I can call it by appending parentheses with the parameter I want to double:

>>> twice(2)
4

So, if you do foo.M(J), you’re calling whatever foo.M is. Assuming you know what you’re doing, it’s probably a function.

foo.K = Q on the other hand does not call anything, it simply looks up the attribute K on foo and assigns the new value Q to it. (Theoretically, foo.K could have been a method of foo's class, but it will now be overwritten for this one instance with whatever Q is – you wouldn’t do such a thing on purpose.)

1 Like

I find with understanding OOP it helps to think in terms or real world objects. After all, that’s what it is all about really.

So attributes are data attributable to the object. Or put another way, things that help describe the objects. Functions/methods are the actions that the object can do.

So imagine a human_face class with eyes, ears nose and mouth. The attributes of the human_face might be ‘blue eyes’, ‘big ears’, ‘broken nose’ and ‘small mouth’.

With dot notation (ie to access these attributes) you would have:

human_face.eyes = blue
human_face.ears = big
human_face.nose = broken
human_face.mouth = small

You are assigning values (describing) to the attributes.

Now if you tried tried to call the following then Python would complain;

human_face.mouth(small)

You could describe this request as ‘using the mouth from the human_face class, call with small’. That makes no sense. ‘small’ is attribute of the mouth and doesn’t ‘do’ anything.

But you could create a function that’s callable - so has the parenthesis - that had an associated code block that did something on the class:

def mouth():
    print(“some words spoken”)

Now human_face has a descriptive attribute of small, but also an associated action of talking (sort of… :smile:)

You still cannot run the following without complaint (as the function defined doesn’t take arguments):

human_face.mouth(small)

But you could run the the following that looks similar but behaves completely differently:

human_face.mouth()

This would be the callable action that’s prints some spoken words.

1 Like

You are basically correct. foo.M and foo.J are the same, and when you get a function you’re basically getting an attribute that is a function.

Thanks everyone. Helps clear things up a bit.