In your 1st statement, you are just assigning class A to the variable "instance_of_A".
In your 2nd statement (where you used parenthesis), you are actually creating an instance of class A.
I think you need a little bit of clarity about OOP in python.
Let me explain a bit how OOP works in python:
Class is like a blueprint, and the instance is like a product for that blueprint (class). You can only use the object and not a class (not speaking about static methods)
class Phone:
__balance = 0
__numberOfCalls = 0
def __init__(self):
self.__balance = 1
print("Yeah!, New Phone")
def makeCall(self):
if self.__balance < 1:
print('Please recharge and try again')
return
self.__numberOfCalls += 1
self.__balance -= 1
print("Making call %d" %(self.__numberOfCalls))
In the above example, we have a simple example class Phone.
samsung = Phone() # Yeah!, New Phone
samsung.makeCall() # Making call 1
samsung.makeCall() # Please recharge and try again
Here you can clearly understand that variables inside class Phone ( __balance, __numberOfCalls ) belong to the created instance (Samsung). In our example, Samsung can't make the second call, because it has zero balance (Note: Samsung has zero balance not the Phone). If you create a new phone (may be onePlus), you can make another call.
What parenthesis do with class?
When you call a class it returns a new instance of the class. But when you just assign it to a variable without calling it, no instance is created.
apple = Phone
apple.makeCall() # TypeError: makeCall() missing 1 required positional argument: 'self'
This threw an error(which is expected), because we have not called Phone, so it wont return the instance of the Phone, instead we are assigning Phone(class) to apple.
If you are coming from other languages such as javascript, you may be expected "method not found exception". But here what we got is Type Error, missing positional argument 'self'.
Python takes its own instance as its 1st argument self (the name self is just a convention, not a keyword), that's why we are writing the self in all method declarations. We don't have to pass the instance as parameters, python handles it when you call the method from the instance.
Here comes a new question...
apple = Phone
apple.makeCall(samsung)
Will the above code work?
yes, as I said, you don't have to pass an instance as a parameter when you call the method via the instance itself. Here apple is just a class (not an instance), And as per the previous error, we are passing the required positional argument Samsung(which is an instance of Phone). This is similar to the below code.
samsung.makeCall()
__call__method, which let you create callable objects(columns/index/unique)on any DataFrame it is not callable function but when you use something likesort()/value_sort()they are callable as they bring operation function with them which kind of supports arguments