0

Topic Closed

So I'm learning OOP in python and wanted to test my knowledge. That's what i did

class Student:
    def cantBeStudent():
        print('You don\' classify as a stududent')

    def __init__(self, age, education):
        self.age = age
        self.education = education
        if (self.age < 16) or (self.education < 3):
            cantBeStudent()


student1 = Student(age=18, education=2)

I get name_error when i try to call cantBeStudent(). It says that cantBeStudent is not defined. I can't find my answer on google so I came here.

Edit: Also when i comment out whole cantBeStudent i get SyntaxError on def init

Community
  • 1
  • 1
  • `canBeStudent` is a method (or an attribute that's a function), so you need to reference it, like other attributes, under `self` – Ed Ward Jan 16 '20 at 17:34

5 Answers5

1

You need to add self to the method invocation and declaration:

class Student:
    def cantBeStudent(self): # need self
        print('You don\' classify as a stududent')

    def __init__(self, age, education):
        self.age = age
        self.education = education
        if (self.age < 16) or (self.education < 3):
            self.cantBeStudent() # need self


student1 = Student(age=18, education=2)

OR

You need to invoke cantBeStudent as a static method like so:

class Student:
    def cantBeStudent(): # no self as first argument, therefore static method
        print('You don\' classify as a stududent')

    def __init__(self, age, education):
        self.age = age
        self.education = education
        if (self.age < 16) or (self.education < 3):
            Student.cantBeStudent() # because declaration has no self,
                                    # cantBeStudent belongs to entire Student class


student1 = Student(age=18, education=2)
gabriel.hayes
  • 2,267
  • 12
  • 15
  • Can you explain why does cantBeStudent need self as an argument when doing self.cantBeStudent? – dawid kaprol Jan 16 '20 at 17:36
  • 1
    @david kaprol I also added an example without `self`, you don't need `self` you just need to either use fully static syntax or fully instance-based syntax (i.e., if it is an instance method it needs to be `self.method()`, if it is a static method, it needs to be `Class.method()`) – gabriel.hayes Jan 16 '20 at 17:37
1

When you construct a class, methods that you define must take the instance as the first argument. The class instance is referred to as self (though you could call it anything you wanted):

class X:
    def __init__(self, number):
        self.number = number

    def add_number(self, arg):
        self.number += arg

You see this when you define __init__. All other functions* work this way as well. When you call them like

instance = X(1)

instance.add_number(3)

It's analogous to doing:

instance = X(1)

X.add_number(instance, 3)

It's just calling the method against the instance will automatically pass self for you. When you call that method inside the instance, you need to specify the instance you are calling against, it's just this is called self instead of instance:

class X:
    ~snip~
    def add_number(self, arg):
        self.number += arg

    def increment_number(self):
        # note the self.<method>
        self.add_number(1)

Again, this would be identical to the call:

instance = X(1)

X.increment_number(instance)

Because the instance gets passed in so that it can be called with the appropriate method

* All other functions that are not decorated with @staticmethod or @classmethod

C.Nivs
  • 12,353
  • 2
  • 19
  • 44
0

You should provide self to any function that you want it to be counted as an object's method. If you do not want to provide self that function could be a static function (which means it does not rely on the type of the object itself). Then, you need to clarify that function, by @staticmethod decorator.

nima
  • 1,645
  • 9
  • 18
0

You missed self parameter on cantBeStudent method and when call it from contructor, it should be self.canBeStudent. Like this:

class Student:
    def cantBeStudent(self):
        print('You don\' classify as a stududent')

    def __init__(self, age, education):
        self.age = age
        self.education = education
        if (self.age < 16) or (self.education < 3):
            self.cantBeStudent()

The purpose of self in Python: What is the purpose of the word 'self', in Python?

khanh
  • 1
  • 1
-1

Add self on the function cantBeStudent

class Student:
    def cantBeStudent(self):
        print("You don't classify as a stududent")

    def __init__(self, age, education):
        self.age = age
        self.education = education
        if (self.age < 16) or (self.education < 3):
            self.cantBeStudent()

That happens because you need to specify that the function is contained in the same class of 'self'

If you would done in this way it would had worked:

def cantBeStudent():
        print("You don't classify as a stududent")

class Student:
    def __init__(self, age, education):
        self.age = age
        self.education = education
        if (self.age < 16) or (self.education < 3):
            cantBeStudent()

The main difference is that in the first case, the function is inside the class Student, in the other case the function is out of the class, so don't need the 'self'