You would be aware of class complex
in python. It contains :
>>> dir(complex)
Output :
['__abs__', '__add__', '__bool__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__int__', '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__pow__', '__radd__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', 'conjugate', 'imag', 'real']
Here conjugate
is a method of class complex
. But my doubt here is what are real and imag called as??
In help():
>>>help(complex)
Output:
class complex(object)
| complex(real=0, imag=0)
...
...
...
----------------------------------------------------------------------
| Data descriptors defined here:
|
| imag
| the imaginary part of a complex number
|
| real
| the real part of a complex number
In help(), real and imag are given as data descriptors.
Where in type():
>>> a=1j
>>> type(a.real)
<class 'float'>
>>> type(a.imag)
<class 'float'>
Also we are accessing real and imag as we access class variable inside a class.
classname.class_variable (or) objectname.class_variable
Hence, I got a doubt here. Whether real and imag are a kind of class variables or data descriptors???
Similarly, a doubt in start
, stop
and step
in class range
.
Need clarification for :
Are they data descriptors or a kind of class variables??
If they are data descriptors, kindly explain me why they are called data descriptors???
Any reference links regarding data descriptors related to my doubt are much needed
Thanks in advance
A descriptor is a special kind of object in Python that, when it is stored as a class variable gets special methods run on it when it gets looked up via an instance.
The descriptor protocol is used for several kind of special behavior, such as method binding (how self
gets passed as the first argument). The protocol is made available easily for Python code via the property
type, which is a descriptor you can apply as a decorator to a method so that it gets called when the attribute gets looked up (without needing the user to explicitly call anything).
In your case, the real
and imag
attributes of the complex
type (as well as the three attributes of the range
type) are descriptors, but they're less fancy than those others. Rather, the descriptors are just how attribute access works for instances of immutable builtin classes (that is, ones that are implemented in C, rather than in pure Python). The actual data of a complex
(or range
) object is stored in a C structure. The descriptor allows it to be accessed by Python code. Note that you can't assign to those attributes, because that would break the immutability of the object.
You could implement a similar type with property
:
class MyComplex():
def __init__(self, real=0, imag=0):
self._real = real
self._imag = imag
@property
def real(self):
return self._real
@property
def imag(self):
return self._imag
Here real
and imag
are property
objects, which are descriptors similar to the ones in the builtin complex
type. They're also read only (though the class as a whole is not really immutable).