Differencebetween _Init_ and _Call_

What is the difference between __init__ and __call__?

The first is used to initialise newly created object, and receives arguments used to do that:

class Foo:
def __init__(self, a, b, c):
# ...

x = Foo(1, 2, 3) # __init__

The second implements function call operator.

class Foo:
def __call__(self, a, b, c):
# ...

x = Foo()
x(1, 2, 3) # __call__

Difference between calling __init__() of build-in class and __init__() of user-defined class

First, you don't need those __init__ implementations at all. You could just inherit the superclass implementations. If you actually need to customize construction, then for uStr, you should do it in __new__ instead of __init__.


str doesn't have its own __init__. It does all its initialization in __new__, because str instances are immutable and initializing in __init__ would be mutative. str inherits __init__ from object.

object.__init__ and object.__new__ are a little weird. If exactly one of object.__init__ or object.__new__ are overridden, then the overridden one throws an error if given arguments (beyond self) and the other ignores arguments, to save you the work of having to provide a do-nothing override. However, if both or neither are overridden, then both will throw an error if given arguments (beyond self). You can see this explained in a big comment in the source code.

str implements __new__, but inherits __init__ from object. When you override __init__ and call str.__init__, you're really calling object.__init__.

When you call str.__init__(u_str), you're actually making an object.__init__ call for u_str, the wrong object, rather than for self. Since u_str doesn't have an __init__ override (and since you're only passing one argument, which gets interpreted as self), object.__init__ silently does nothing.

When you call str.__init__(self, u_str), you're making an object.__init__ call for self, but since self has both __new__ and __init__ overridden, object.__init__ complains about the u_str argument.

It doesn't look like you actually need to override construction at all in your subclasses. If you do, the correct way to customize construction of a str subclass is to override __new__. If for some strange reason you had to call str.__init__, the correct call would be str.__init__(self) or super().__init__(). Since object.__init__ doesn't do any initialization, you could also leave out the superclass constructor call.

`__new__` and `__init__` on class and object

The biggest part of the picture you're probably missing is that __new__ is a staticmethod, special-cased to be one even if you don't use the @staticmethod decorator.

When calling a method through super(), super() performs the same kind of argument binding that would be performed normally for that kind of method (using the descriptor protocol). For a staticmethod like __new__, that means no arguments are automatically bound, so cls has to be passed explicitly. For an instance method like __init__, that means self is bound automatically, which is why you don't have to pass self to super().__init__.

__call__ or __init__ called here? Don't undestand which and why

I believe this is what you're looking for.

The behaviour of calling an object in Python is governed by its type's __call__, so this:

OAuth2Bearer(args)

Is actually this:

type(OAuth2Bearer).__call__(OAuth2Bearer, args)

What is the type of OAuth2Bearer, also called its "metaclass"? If not type, the default, then a subclass of type (this is strictly enforced by Python). From the link above:

If we ignore error checking for a minute, then for regular class instantiation this is roughly equivalent to:

def __call__(obj_type, *args, **kwargs):
obj = obj_type.__new__(*args, **kwargs)
if obj is not None and issubclass(obj, obj_type):
obj.__init__(*args, **kwargs)
return obj

So the result of the call is the result of object.__new__ after passed to object.__init__. object.__new__ basically just allocates space for a new object and is the only way of doing so AFAIK. To call OAuth2Bearer.__call__, you would have to call the instance:

OAuth2Bearer(init_args)(call_args)

What is the difference between call() and __call__() method in python?

call() is just a regular method that you can call on an instance of a class, e.g. foo.call(...).

__call__() is a special method that makes the instance itself callable. So instead of doing foo.call(...) you can just do foo(...). (You can also do foo.__call__() still.)

What is the difference between init__ and __init__ in python class?

__init__ is the hook used to initialize your instance. (it is always called when you create an instance).

init__ is just a class method with a wonky name.

You need to show us your code; if something is broken when you have a method named __init__ you made a mistake there. Renaming it to init__ just means it won't be called automatically, thus not triggering your coding mistake.

In the comment you refer to, the author did use __init__ in his comment but forgot to escape the leading underscores, and they were interpreted as code to start bold text instead:

__this is bold__

becomes this is bold. Note that the trailing __ on __main__ also is lost in that comment.

In your updated code, you are trying to override the __init__ method of a (subclass) of tuple, which is a special case. By renaming the __init__ method to init__ you created a different method and did not run into this common problem at all.

See Subclassing Python tuple with multiple __init__ arguments for more detail on why this is a problem; you have to create a __new__ method instead. __new__ is the factory method to create instances, __init__ then initializes the data. But that doesn't work on immutable types such as namedtuple or tuple, since you are not supposed to change the instance after the factory created it.

In this specific case, you do not need an __init__ or a __new__ method at all because the namedtuple subclass Point already takes care of the initialization of the x, y and z attributes. By renaming __init__ to init__ you made things work, but you do end up with a pointless init__ method that you'll never use. Just delete it.

__call__ vs. __init__: Who gets the arguments? Who gets called first?

__call__ is only called on an instance that defines itself as callable.

__init__ is the initializer that provided an instance of the class

If you do something like

MyObject()() Then you are initliaizing THEN calling.

Using your own example

class User(object):
def __init__(self, loginName, password):
self.loginName = loginName
self.password = password

def __call__(self):
if self.login():
return self
return None

def login(self):
database = db.connection
return database.checkPassWord(self.loginName, self.password)

a = User("me", "mypassword")
a = a() # a is now either None or an instance that is aparantly logged in.


Related Topics



Leave a reply



Submit