-4

Consider this code:

class example(object):

    def __init__ (): # No self
        test()       # No self

    def test(x,y):   # No self
        return x+y 

    def test1(x,y):  # No self
        return x-y

print(example.test(10,5))
print(example.test1(10,5))

15
5

This works as expected. I believe I can write a whole program not using self. What am I missing? What is this self; why is it needed in some practical way?

I have read a lot about it - (stack, Python documentation), but I just don't understand why it's needed, since I can obviously create a program without it.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • 1
    You **are** using `self` -- you have simply renamed it `x`. You are calling **unbound methods** and passing the first argument explicitly instead of implicitly. You will not be able to instantiate your class because your `__init__` is wrong and will cause a `TypeError`. – Two-Bit Alchemist Aug 11 '16 at 17:57
  • 1
    How is this object-oriented programming ? You are using a class as a namespace, without creating objects with it. Consider reading a course on OOP. – baxbaxwalanuksiwe Aug 11 '16 at 18:01
  • I don't know why everyone is complaining about OOP because you could delete `__init__` and decorate the `test*` methods with `@staticmethod` and it would work perfectly fine, as intended. – Two-Bit Alchemist Aug 11 '16 at 18:06
  • This question needs more help than we can provide. We like helping people, but sometimes the person needs to help themselves first by reading a book on the language, the on-line documentation, or asking someone they know who can help them. Once you understand the topic a little better, we invite you to edit this question, fix the obvious mistakes, and get it re-opened. In particular, you need to learn what an **object** is, and how it relates to a **class**. All you've done here is to put a useless class shell around some independent functions. – Prune Aug 11 '16 at 18:08
  • See, but in def __init__ () there is no self as well. Things are just delegated to methods and it works perfect. – self.class Aug 11 '16 at 18:09
  • @self.class You're not **using** `__init__`. You never instantiate the class. `ex = example()` is a `TypeError` using your code. – Two-Bit Alchemist Aug 11 '16 at 18:09
  • Prune, there is no self in def __init__ and it works. How come? I get correct results, I get exactly what I want. I am sure if i would contininue with developing, I would get wanted results. – self.class Aug 11 '16 at 18:10
  • @Two-Bit Alchemist, you get TypeError?? I get none, I get results 15 and 5 – self.class Aug 11 '16 at 18:12
  • @self.class Did you write `ex = example()` like I said? You're not instantiating your class or using bound methods normally, which is why you're not seeing any usage of `self`. – Two-Bit Alchemist Aug 11 '16 at 18:12
  • yes yo ucan store def in static class, but if you want create object you need self. you can programming without object too. –  Aug 11 '16 at 18:16
  • @self.class its not raising an error because you never call `__init__()`. It is called on the creation of an object, which you never do. You are just calling functions inside a class that have no reason to be inside a class if that's all you're doing. – pretzlstyle Aug 11 '16 at 19:35
  • @Two-BitAlchemist Sure, but then putting those functions in a `class` is unnecessary. – pretzlstyle Aug 11 '16 at 19:35

3 Answers3

1

You can perfectly create a program without it. But then you'd be missing one of the key features of classes. If you can do without self, I'd argue you can do without classes and just do something purely with functions :)

Classes allow you to create objects which have a PROPERTY associated to them, and self allows you to access those values. So say you have a square.

g code:

class Square(object):

    def __init__ (self, length, height):
        self.length = length # THIS square's length, not others
        self.height = height # THIS square's height, not other

    def print_length_and_height(self):
        print(self.length, self.height) # THIS square's length and height



square1 = Square(2,2)
square2 = Square(4,4)
square1.print_length_and_height() # 2 2
square2.print_length_and_height() # 4 4

Now, this example is quite silly, of course, but i think it shows what SELF specifically is for: it refers to the particular instance of an object.

By all means, if you don't see the point to it, just do away with classes and just use functions, there nothing wrong with that.

joaquinlpereyra
  • 956
  • 7
  • 17
  • This is a nice answer to another question. It really doesn't get at the problems with the OP. – Two-Bit Alchemist Aug 11 '16 at 18:06
  • 1
    I tried to explain something he evidently doesn't get while telling him his structure is wrong because he is using classes for absolutely nothing, exactly like the top voted answer. – joaquinlpereyra Aug 11 '16 at 18:17
1

You haven't utilised a class or object properly. Cutting out the garbage code, your program reduces to:

def test(x,y): #No class
    return x+y 

def test1(x,y): #No class
    return x-y

print(example.test(10,5))
print(example.test1(10,5))

Output:

15
5

Your "class" is no more useful than if you wrapped your program in the nested structures:

if True:
    for i in range(1):
        ...

A proper object will have attributes (data fields) and functions that operate on that data (see below). Your code has an empty object; hence, you have nothing on which to operate, no need for self, and no need for a class at all.

Rather, use a class when you need to encapsulate a data representation and associated operations. Below, I've reused some of your code to make example do some trivial complex number work. There are many extensions and improvements to make in this; I kept it relatively close to your original work.

class example(object):

    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        sign = ' + ' if self.b >= 0 else ' - '
        return str(self.a) + sign + str(abs(self.b)) + 'i'

    def add(self, x): 
        self.a += x.a
        self.b += x.b

    def sub(self, x): 
        self.a -= x.a
        self.b -= x.b

complex1 = example(10, 5)
complex2 = example(-3, 2)
complex1.add(complex2)
print(complex1)
complex2.sub(complex1)
print(complex2)

Output:

7 + 7i
-10 - 5i
Prune
  • 76,765
  • 14
  • 60
  • 81
  • 1
    Still no explanation of where self went, or unbound methods, or why OP is succeeding without using self. Every answer here is pretty much dancing around the problem and making stylistic complaints. – Two-Bit Alchemist Aug 11 '16 at 18:14
  • @Two-BitAlchemist I don't think its a stylistic complaint. The usage of `self` implies the existence of an object, which OP has never created. He is succeeding without `self` because he never creates an `example` object and thus `__init__()` (which would fail) is never called. The answer @Prune gives is spot on. He is complaining `self` not being necessary, but never uses any objects to _be_ "itself". If he doesn't use OO programming, there is no entity to which `self` refers to, so why would it be needed? – pretzlstyle Aug 11 '16 at 19:33
  • @jphollowed I totally agree that OP's code should be written without classes if left as is, but I don't see how anything in this answer _explains_ why that is. It calls OP's OOP "garbage code" and "useless" but doesn't say why the class isn't getting used properly, and doesn't explain what I was fighting to say in comments, which is that OP _does_ have a `self` parameter, as well as a `TypeError` lurking in his code if the object is ever used. – Two-Bit Alchemist Aug 11 '16 at 20:39
  • @Two-BitAlchemist: Thanks for the kick; better example added. – Prune Aug 11 '16 at 21:17
-1

Are you familiar with Object-Oriented Paradigm?
If you don't you should check it. Python is a Object-Oriented Language and self lets you define your object properties.
An example:
You have a class named Vehicle. A vehicle could be a bike, a car, even a plane. So something you can include is a name and a type.

class Vehicle():
  def init(self, name, type): # Constructor
    self.name = name
    self.type = type
  def info(self):
    print("I'm a ")
    print(self.name)

That's all, now you have a vehicle with name and type. Every instance of Vehicle would have a name and a type different or not and every intance can access its own variables. I'm sorry I can't explain it better. Firstable you need to know Object-Oriented Paradigm knowledge. Please comment my answer if you have doubts & I'll answer you or give a link where it comes explained better.

  • 1
    You can complain about OOP all you want but you haven't touched on any problems in OP's code, and you could add `@staticmethod` to every one of his methods and it would work as expected (except `__init__`), and still be OOP. – Two-Bit Alchemist Aug 11 '16 at 18:05
  • "What is this self, can you please tell me why is it needed in some practical way?" How have you addressed the question of OP? – roganjosh Aug 11 '16 at 18:14
  • class example(): def __init__(self, car, model): car = car model = model print(example("bmw", 'new-model')) – self.class Aug 11 '16 at 18:17
  • @Two-BitAlchemist He doesn't understand why `self` is needed because he is using a `class` as if its just a module or package with some functions in it. – pretzlstyle Aug 11 '16 at 19:39