Reputation: 10548
I'm just trying to wrap my head around the syntax here:
# some data
import numpy as np
x = linspace(0, 1, 100)
x.sum() # works with brackets
> 50.0
x.shape # works without brackets
> (100,)
x.shape() # fails with brackets
> TypeError
Why is it that some methods/functions have brackets while others don't?
Upvotes: 0
Views: 803
Reputation: 152725
When you access an attribute of your instance you really access a descriptor. There are three common cases:
The descriptor returns a function like x.sum
, that returns a bound function. Bound because the first argument to that function will be x
. You obviously need to call ()
that function to give you an result.
There are class and instance attributes, that simply return a value either saved in x.__dict__
or x.__class__.__dict__
. You don't need to call anything to get these. However x.shape
isn't one of those!
There are properties
, when you access these it will implicitly call a method of your class. In general properties, say x.something
, are equivalent to x.__class__.something.fget(x)
. Seems weird but works ... sort of. The important thing here is that you normally don't need to call it directly ()
because you can just do x.something
.
But that's technical, maybe the simpler explanation is better to remember:
sum
is a method. Methods should be called. To call a function or method you need the ()
.shape
is a property (but could also be an attribute) and you don't need to call those! It could return a function as well but in this case it returns a tuple
and you can't call a tuple
instance.Upvotes: 3