I have tried and errored a reasonable amount of times

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Aug 31 05:05:15 EDT 2014


Seymore4Head wrote:

> That would work now, but I didn't even know no.isupper() was command
> until 15 min ago.  :)
> 
> I have been told that one is a method and the other calls a method.  I
> still have to learn exactly what that means.  I'm getting there.

Indeed you are :-)

"Command", in Python, doesn't really have any formal meaning. Sometimes we
use it informally, e.g. I might say that the `import` statement is a
command that loads a module.

What is the difference between "is a method" and "calls a method"? In
practice, there's not much difference between methods and functions, so I'm
going to talk about functions. Pretty much everything I say will apply to
methods too.

[Reminder: functions are "stand alone" objects that live inside a module,
but not a class. Methods are just like functions, but they live inside
classes. There are a few other differences, but conceptually they're the
same thing.]

Let's create a function. Copy and paste this into an interactive session:

def spam(n):
    return "spam"*n


This takes the indented body of the function (in this case, a single line of
source code), compiles it, shoves the compiled bytecode somewhere Python
can get to later, creates a function object which includes that compiled
bytecode, and assigns that function object to the variable called "spam".
spam is a variable like any other, and we can print it, put it inside a
list, assign it to another variable, and so forth:

py> print(spam)
<function spam at 0xb7d05344>
py> mylist = [None, 1, "two", spam]
py> print(mylist)
[None, 1, 'two', <function spam at 0xb7d05344>]
py> x = spam
py> print(x)
<function spam at 0xb7d05344>


Because functions are objects, they have attributes and methods like other
objects:

py> spam.__name__
'spam'
py> dir(spam)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', 
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__', 
'__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', 
'__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__']

See how all of those attributes start and end with double underscores?
These "dunder" (Double UNDERscore) attributes are reserved for use by
Python, and 99.9% of the time you don't need to pay any attention to them
in the least. But they are there, Python uses them, and on (rare) occasions
so will you.

(Feel free to look but not touch: you can print out the value of any dunder
attribute, but don't try changing them until you know what you're doing.)

So far, we've just been treating spam as an object. What sort of object?
It's a function object, like there are int objects, str objects, float
objects, list objects, and so on. Unlike all those other kinds of object,
function objects are callable: if you put round brackets (parentheses)
after the variable, the object assigned to that variable will be called:

py> spam
<function spam at 0xb7d05344>
py> spam(3)
'spamspamspam'


Remember how we assigned spam object to the variable "x"? That means that x
is another name for spam:

py> x(4)
'spamspamspamspam'


And since spam has been placed inside a list, we have a third way to refer
to it:

py> mylist[3]  # Retrieve the function.
<function spam at 0xb7d05344>
py> mylist[3](2)  # And call it.
'spamspam'


Note that this does NOT mean that we have three copies of the function. We
only have a single copy of the function. But we have three different ways
of referring to it:

* the canonical name, "spam", which is the name it knows itself by;
* the name "x";
* the list item mylist[3].

Any of those will give you the function object itself, but without calling
it. Only when you use round brackets (parentheses) will the function
actually be called.



-- 
Steven




More information about the Python-list mailing list