Ahmed AbdelKhalek
Ahmed AbdelKhalek

Reputation: 192

Questions related to classes

I have a problem understanding some concepts of data structures in Python, in the following code.

class Stack(object):                        #1
    def __init__(self):                     #2
        self.items=[] 

    def isEmpty(self):
         return self.items ==[]

    def push(self,item):
        self.items.append(item)

    def pop(self):
        self.items.pop()

    def peak(self):
        return self.items[len(self.items)-1]

    def size(self):
        return len(self.items)

s = Stack()
s.push(3)
s.push(7)

print(s.peak())
print (s.size())
s.pop()
print (s.size())

print (s.isEmpty())
    1. I don't understand what is this object argument
    2. I replaced it with (obj) and it generated an error, why?
    3. I tried to remove it and it worked perfectly, why?
    1. Why do I have __init__ to set a constructor?
    2. self is an argument, but how does it get passed? and which object does it represent, the class it self?

Thanks.

Upvotes: 2

Views: 83

Answers (3)

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

Point 1:

Some history required here... Originally Python had two distinct kind of types, those implemented in C (whether in the stdlib or C extensions) and those implemented in Python with the class statement. Python 2.2 introduced a new object model (known as "new-style classes") to unify both, but kept the "classic" (aka "old-style") model for compatibility. This new model also introduced quite a lot of goodies like support for computed attributes, cooperative super calls via the super() object, metaclasses etc, all of which coming from the builtin object base class.

So in Python 2.2.x to 2.7.x, you can either create a new-style class by inheriting from object (or any subclass of object) or an old-style one by not inheriting from object (nor - obviously - any subclass of object).

In Python 2.7., since your example Stack class does not use any feature of the new object model, it works as well as an 'old-style' or as a 'new-style' class, but try to add a custom metaclass or a computed attribute and it will break in one way or another.

Python 3 totally removed old-style classes support and object is the defaut base class if you dont explicitely specify one, so whatever you do your class WILL inherit from object and will work as well with or without explicit parent class.

You can read this for more details.

Point 2.1 - I'm not sure I understand the question actually, but anyway:

In Python, objects are not fixed C-struct-like structures with a fixed set of attributes, but dict-like mappings (well there are exceptions but let's ignore them for the moment). The set of attributes of an object is composed of the class attributes (methods mainly but really any name defined at the class level) that are shared between all instances of the class, and instance attributes (belonging to a single instance) which are stored in the instance's __dict__. This imply that you dont define the instance attributes set at the class level (like in Java or C++ etc), but set them on the instance itself.

The __init__ method is there so you can make sure each instance is initialised with the desired set of attributes. It's kind of an equivalent of a Java constructor, but instead of being only used to pass arguments at instanciation, it's also responsible for defining the set of instance attributes for your class (which you would, in Java, define at the class level).

Point 2.2 : self is the current instance of the class (the instance on which the method is called), so if s is an instance of your Stack class, s.push(42) is equivalent to Stack.push(s, 42).

Note that the argument doesn't have to be called self (which is only a convention, albeit a very strong one), the important part is that it's the first argument.

How s get passed as self when calling s.push(42) is a bit intricate at first but an interesting example of how to use a small feature set to build a larger one. You can find a detailed explanation of the whole mechanism here, so I wont bother reposting it here.

Upvotes: 2

Metareven
Metareven

Reputation: 842

1

object here is the class your new class inherits from. There is already a base class named object, but there is no class named obj which is why replacing object with obj would cause an error. Anyway in your example code it is not needed at all since all classes in python 3 implicitly extends the object class.

2

__init__ is the constructor of the object and self there represents the object that you are creating itself, not the class, just like in the other methods you made.

Upvotes: 2

Błotosmętek
Błotosmętek

Reputation: 12927

  1. object is a class, from which class Stack inherits. There is no class obj, hence error. However, you can define a class that does not inherit from anything (at least, in Python 2).
  2. self represents an object on which the method is called; for example when you do s.pop(), self inside method pop refers to the same object as s - it is not a class, it is an instance of the class.

Upvotes: 3

Related Questions