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.
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'>
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'>
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.
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'>
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'>