Apollo
Apollo

Reputation: 9054

__init__ Python Syntax

I created a class for Food items. I'm wondering why in def __init__(self, type) there are two arguments but when I call Food('Meat') I only pass one argument. I assume this is because __init__ is special somehow?

class Food(object):

    def __init__(self, type):
        self.type = type

    def cook_food_item(self):
        if self.type == 'Meat':
            print 'Grill it!'
        elif self.type == 'Vegetable':
            print 'Boil it!'
        elif self.type == 'Dairy':
            print 'Churn it!'

hot_dog = Food('Meat')
hot_dog.cook_food_item()

Upvotes: 0

Views: 242

Answers (3)

Joe
Joe

Reputation: 16831

There's nothing special about __init__ here.

In Python, you have two kinds of methods: bound and unbound. Methods defined in a class are usually bound, which let you write myobj.mymethod() instead of MyClass.mymethod(myobj). Unbound methods have no self argument and act just like regular functions.

To illustrate the point, you can create an unbound method like this:

def myfunction(x):
    return x

class MyClass(object):
    def __init__(self):
        self.unbound = myfunction

    def bound(self, x):
        print('MyClass.bound called with', self)
        return x

myobj = MyClass()
print(myobj.unbound(42))
print(myobj.bound(42))

Note that myfunction (and therefore myobj.unbound) have no access to self unless you explicitly pass it in. So in general, bound methods like MyClass.bound are the tool of choice when writing classes. __init__ is no different. It wouldn't be very useful as an unbound method.

Upvotes: 0

Adam Smith
Adam Smith

Reputation: 54163

All methods in a class pass the class instance as their first argument, including __init__. This is true for the other method in your class as well: def cook_food_item(self).

If you had another method that took an actual argument, you'd put that argument after self, leaving something like:

class Food(object):
    ...

    def eat_with(self, drink):
        print("Eating a " + self.type + " while drinking a " + drink)

>>> hot_dog = Food("hot dog")
>>> hot_dog.eat_with("coke")
Eating a hot dog while drinking a coke

Behind the scenes this is doing something kind of like

>>> hot_dog.eat_with("coke")
# becomes something resembling
hot_dog.__class__.eat_with(hot_dog, "coke") # hot_dog.__class__ is Food

Upvotes: 0

André Fratelli
André Fratelli

Reputation: 6068

__init__ is special indeed because it's a magic method, although that's not what makes it receive self as a first parameter. Being a class method does that. Every method receives self as a first argument, which is passed automatically by Python. I strongly recommend you read the Python basics, like classes, in this case.

Upvotes: 2

Related Questions