Reputation: 1062
My apologies if this is a stupid question but
if we have
x=3+5j
then
x.imag
would give its imaginary part
x.conjugate()
would give its complex conjugate. Why do we need to put a ()
to call the conjugate function?
I am thinking whether x
can be thought to be a struct in C++
imag
is a public attribute of x
, where conjugate
is a member function. Is this way of thinking correct? I apologise if this makes no sense. Admittedly, my knowledge of C++ and Python are both quite limited.
Upvotes: 0
Views: 931
Reputation: 5609
x
is not a struct
, it is an object
of type complex
(although sometimes it helps to think of object
s as struct
s with methods bound to them).
>>> type(x)
<class 'complex'>
>>> x = 3+5j
>>> type(x)
<class 'complex'>
x.imag
is not a function, it's an attribute
of the object x
that is a float
object. An attribute
does not have to be called with the parentheses ()
in order to retrieve its value. Its value is 5
in your example. You can test if it's a function by calling callable
on it. float
objects are not callable.
>>> x.imag
5.0
>>> type(x.imag)
<class 'float'>
>>> callable(x.imag)
False
x.conjugate
is a function, since callable(x.conjucate)
returns True
. You call the function by putting the parentheses ()
after it with the function parameters inside the parentheses. When called, it returns a new object
of type complex
, which in turn also has the method conjugate
which can be called.
>>> x.conjugate
<built-in method conjugate of complex object at 0x00000000034D2C90>
>>> callable(x.conjugate)
True
>>> x.conjugate()
(3-5j)
>>> type(x.conjugate())
<class 'complex'>
>>> x.conjugate().conjugate()
(3+5j)
Upvotes: 1
Reputation: 1786
So, on top of other problems, you sometimes have programming functions which arnt the same thing as maths functions. Generally speaking, an struct that has functions (which is basically what an object is), is where the function always has a starting context.
Historically before objects, you would have to mkae a function that took the A and B, so you would make a function called addthing(A, B)
, where now, we can make a function on the thign called add, so you can do A.add(B)
. Ok.. these are functions on the object
But objects can also have properties. Now some programmers will tell you you shouldnt have public things, you should use getters and setters, and then C# does something awesome to make that better: but I like public properties, so I can imagine making a 'class' (which is the definition of an object) being representing a coordinate or a vector, so i can define it to have an X and a Y, so these arn't functions but properties.
Wierd bit 1) But we want to do things sometimes a bit implicitly. like doo vector = vector_a + vector_b
that would be awesome right? Well, you can! objects inherit basic Objects, but the default __add__
function on the object doesnt know how to add nother one together, so I can implement that on my object. Theres actually tons of these default functions which are called... effectively the compile rewrites anything like x = y + z
into x = y.__add__(z)
. What else can you override? __str__
is whats called when you convert it to a string (like print(mycoord)
gets converted (effectivly) into print(str(mycoord))
which in turn is print(mycoord.__str__())
. Theres also a ton of things like comparison, meaning your objects can be sorted by lists and other cool things...
wierd bit 2) ok sometimes you want a property to actually be a function. WHAAAAAAT? We often call these 'getters and setters'. They look like a property or attribute, but they're actually a function... so..
# in a class...
@property
def x(self):
"""I'm the 'x' property."""
return self._x
# sometime later...
print(myobject.x) # <-- effectivly calls myobject.x()
now this means you can do things on the setter where you might validate the input, control how its set, maybe force it to be a particular type (not quite inline with the zen of python, but sometimes very useful).
Hope that helps!
Upvotes: 2