Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class instantiation and 'self' in python

I know a ton has been written on this subject. I cannot, however, absorb much of it. Perhaps because I'm a complete novice teaching myself without the benefit of any training in computer science. Regardless, maybe if some of you big brains chime in on this specific example, you'll help other beginners like me.

So, I've written the following function which works just fine when I call it (as a module?) as it's own file called 'funky.py':

I type the following into my terminal:

python classy.py

and it runs fine.

def load_deck():
    suite = ('Spades', 'Hearts')
    rank = ('2', '3')
    full_deck = {}
    i = 0
    for s in suite:
        for r in rank:
            full_deck[i] = "%s of %s" % (r, s)
            i += 1
    return full_deck

print load_deck()

When I put the same function in a class, however, I get an error.

Here's my code for 'classy.py':

class GAME():
    def load_deck():
        suite = ('Spades', 'Hearts')
        rank = ('2', '3')
        full_deck = {}
        i = 0
        for s in suite:
            for r in rank:
                full_deck[i] = "%s of %s" % (r, s)
                i += 1
        return full_deck
MyGame = GAME()
print MyGame.load_deck()

I get the following error:

Traceback (most recent call last):
File "classy.py", line 15, in <module>
print MyGame.load_deck()
TypeError: load_deck() takes no arguments (1 given)

So, I changed the definition line to the following and it works fine:

def load_deck(self):

What is it about putting a function in a class that demands the use of 'self'. I understand that 'self' is just a convention. So, why is any argument needed at all? Do functions behave differently when they are called from within a class?

Also, and this is almost more important, why does my class work without the benefit of using init ? What would using init do for my class?

Basically, if someone has the time to explain this to me like i'm a 6 year-old, it would help. Thanks in advance for any help.

like image 434
DBWeinstein Avatar asked Aug 06 '12 23:08

DBWeinstein


People also ask

What is class instantiation in Python?

In short, Python's instantiation process starts with a call to the class constructor, which triggers the instance creator, . __new__() , to create a new empty object. The process continues with the instance initializer, . __init__() , which takes the constructor's arguments to initialize the newly created object.

What is class and self in Python?

The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.

What is __ self __ in Python?

self represents the instance of the class. By using the “self” we can access the attributes and methods of the class in python. It binds the attributes with the given arguments. The reason you need to use self. is because Python does not use the @ syntax to refer to instance attributes.

Can you instantiate a class within itself Python?

The class itself is not defined until after the class block finishes executing, so you can't make use of the class inside its own definition. You could use a class decorator or a metaclass to add your desired class variable after the class is created. Here's an example with a decorator.


1 Answers

Defining a function in a class definition invokes some magic that turns it into a method descriptor. When you access foo.method it will automatically create a bound method and pass the object instance as the first parameter. You can avoid this by using the @staticmethod decorator.

__init__ is simply a method called when your class is created to do optional setup. __new__ is what actually creates the object.

Here are some examples

>>> class Foo(object):
    def bar(*args, **kwargs):
        print args, kwargs

>>> foo = Foo()
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0x01C9FEB0>>
>>> Foo.bar
<unbound method Foo.bar>
>>> foo.bar()
(<__main__.Foo object at 0x01C9FEB0>,) {}
>>> Foo.bar()

Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    Foo.bar()
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)
>>> Foo.bar(foo)
(<__main__.Foo object at 0x01C9FEB0>,) {}
like image 138
Antimony Avatar answered Sep 23 '22 15:09

Antimony