Is __init__ always required? [duplicate]
Asked Answered
V

2

5

Okay. So I saw someone using this code, and I understand it, I so I'm going to use it. Is it necessary to have __init__?

class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print self.x + ' ' + foo

a = A() 
a.method_a('Sailor!')

Couldn't I just do something like this:

class A(object):
    def method_a(self):
        print "Hello, Sailor!"

a = A()
print a.method_a()

When I do do this, I do get the "Hello, Sailor!" but I get a "None" right below it? Does that have to do with the __init__? Someone explain.

Vidar answered 24/3, 2014 at 4:43 Comment(3)
The None has nothing to do with class/init issues, it's just because your method_a() doesn't have a return value. Hopefully that reduces the confusion somewhat.Sporozoite
If you leave it out, your classes' __init__ is the one inherited from object (which does nothing). That is fine.Quintus
Omit print from print a.method_a(), and None you shall have no more.Bove
V
8

What you're asking doesn't have much to do with __init__. You can do what you say in your second example, but it doesn't do the same thing as the first example.

In the first example, it prints "Hello" followed by an argument that you pass to the method. You can make it print something besides "sailor" by passing something else in:

>>> a.method_a('buddy!')
Hello buddy!

In the second example, it always prints "Hello, Sailor!" and you can't make it print anything else.

As for __init__, in your example, the __init__ is not that useful, because all it does is set an attribute x that is the same string for each object. You should use __init__ if you want to "set up" each object as you create it. In your example, this setup is not that interesting because it's always the same for every object. You don't have to use __init__, but there's usually not much point in creating objects that don't have some sort of individual state attached to them. Here is a more illustrative example:

class Greeter(object):
    def __init__(self, greeting):
        self.greeting = greeting

    def greet(self, who):
        print self.greeting + ", " + who + "!"

Then you can do this:

>>> hello = Greeter("hello")
>>> hello.greet('sailor')
hello, sailor!
>>> howdy = Greeter('Howdy')
>>> howdy.greet('partner')
Howdy, partner!

Here, when you create a Greeter, you specify the greeting. That greeting is stored with the object, and used whenever it greets someone. The point of the __init__ is that you can make multiple greeters with different greetings.

Notice that I still pass in the person to greet when I call greet. So the greeting (hello or howdy in this example) is set when I create the object, but the person to greet is specified anew each time I use the object to greet.

Generally you will mix these two kinds of things in your code. Some pieces of information are "part of the object" and you will handle them in __init__ and store them on the object. Others are more specific or transitory information that you will pass in as function arguments for each task you want to do. The balance between these depends on what the class is supposed to do, but the above example should illustrate the difference.

Also, neither of these has anything to do with why you see "None" printed. dr_jimbob has explained why that happens.

Violist answered 24/3, 2014 at 4:52 Comment(0)
J
4

You can safely leave out __init__ if you do not need to set any attributes or do any other initialization to the object when it is created. The reason you get None is there's no return type to your method_a(). So when you print it, you get None.

If you had:

class A(object):
    def method_a(self):
        return "Hello, Sailor!"
a = A()
print a.method_a()

You will not see the None (as method_a returns a string) and then later you call print on the string to display it.

Or if you had:

class A(object):
    def method_a(self):
        print "Hello, Sailor!"
a = A()
a.method_a()

This time calling method_a prints the string, but since you aren't printing this result (just calling it) you don't see a None displayed.

Jeffreys answered 24/3, 2014 at 4:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.