Function is an object of class in python?

Question:

I read that a function is an object of a class in python.To further understand, i did below:

>>> a=10
>>> a.__class__
<type 'int'>
>>> int.__class__
<type 'type'>
>>>
>>>
>>> def T1():
...     print 'test'
...
>>> T1.__class__
<type 'function'>
>>> function.__class__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'function' is not defined

Q:why does the interpreter throw an error in the second case and not in the first case? I was expecting it to return <type 'type'>.Please correct my understanding.

Asked By: fsociety

||

Answers:

There is a function type, but there is no built-in name for it. You can find another reference there under the types module:

>>> import types
>>> def T1():
...     pass
...     
>>> T1.__class__ is types.FunctionType
True
>>> print(repr(types.FunctionType))
<class 'function'>

So, the only difference here is that function is not a built-in name, unlike names such as int. If you want that name in your namespace for some reason, you can just bind it:

>>> function = type(lambda: 0)
>>> function
<class 'function'>
Answered By: wim

Think of it this way. Say you create your own metaclass (class of a class), and a subclass of your metaclass (which is itself just a class):

>>> class MyMeta(type): # <-- a custom metaclass, similar to function
        pass

>>> print(MyMeta.__name__)
MyMeta
>>> print(__class__)
<class 'type'>

>>> class MyClass(metaclass = MyMeta):
        pass
>>> print(MyClass.__class__)
<class 'MyMeta'>

Now, we will delete the identifier MyMeta:

>>> del MyMeta

Can you still get to the metaclass object that was represented by MyMeta although MyMeta has been deleted? Sure:

>>> print(MyClass.__class__)
<class 'MyMeta'>

So there is still a reference to the metaclass object in the MyClass dict.

However, the name MyMeta is now invalid, since it was deleted:

>>> class MyClassTwo(metaclass = MyMeta):
        pass
NameError!!
>>> print(MyMeta.__name__)
NameError!!
>>> print(MyMeta)
NameError!!

IMPORTANT: The metaclass name has been deleted, not the metaclass object itself.

Therefore you can still access the metaclass object this way:

>>> class MyClassTwo(metaclass = MyClass.__class__):
        pass

So it is with the function name (which is itself kind of like a built-in metaclass; i.e., it is the class, or type, of function objects)- by default, the name function doesn’t exist in an interactive Python session. But the object does still exist. You can access it this way:

>>> def f(): pass
>>> f.__class__.__class__
<class 'type'>

And if you like, you can even go ahead and assign the name function to the function <class 'type'> object (although there’s not much reason to do that):

>>> function  = f.__class__
>>> print(function)
<class 'function'>
>>> print(function.__class__)
<class 'type'>
Answered By: Rick
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.