sharp
sharp

Reputation: 2158

TypeError: missing 1 required positional argument: 'self' vs as alias during import

I am new to defining self and calling functions in another python file. I am using python 3.7. Suppose I have two python file, one with the class (name.py) and another calling this class function in another file (test.py). I am trying to understand why python shows error in Try#1 but not in the #2? Try#1 as defining as alias, but what does this do? It seems like it is not initializing it?

Main file with class function: name.py

class NameEmployee:

    def __init__(self):
        pass

    def first_name(self,x):
        return print('Hello ',x,'!')

File to run: test.py

Try #1: NOT WORKING

from names import NameEmployee as ne
ne.first_name(x = 'John') 

Results in --> TypeError: first_name() missing 1 required positional argument: 'self'

Try #2: WORKING

from names import NameEmployee
ne = NameEmployee()
ne.first_name(x = 'John')

Results in --> Hello John !

Upvotes: 0

Views: 1632

Answers (4)

Abu Bakar Siddik
Abu Bakar Siddik

Reputation: 459

You need to create a object of the class to implement the methods of the class. In the first example you didn't create a object and that's why a TypeError was risen.

Upvotes: 0

Seyed_Ali_Mohtarami
Seyed_Ali_Mohtarami

Reputation: 1164

You paid attention to this issue.you have to consider one of these two styles Only for libraries like os---(But NameEmployee is a class):

from os import path as p

or

import os.path as p

For more information go to:https://www.python.org/dev/peps/pep-0221/

Upvotes: 0

Tomerikoo
Tomerikoo

Reputation: 19422

It's important to establish that this has nothing to do with "aliasing", rather the simple fact that the two pieces of code are not equivalent!

Let's start by simplifying the Second try. We will simply remove the use of an intermediate variable, to get:

from names import NameEmployee
NameEmployee().first_name(x='John')

Now, going to the first try, let's just remove the alias for now:

from names import NameEmployee
NameEmployee.first_name(x='John')

Now you can clearly see the difference: The second try actually calls (with those ()) the constructor, thus implicitly passing self which is the newly created instance.

But the first try calls the first_name method directly from the class, and not an instance of the class, so self is never passed (NameEmployee().first_name(x='John') is equivalent to NameEmployee.first_name(NameEmployee(), x='John') while NameEmployee.first_name(x='John') is just what it is - a call to first_name without passing self...).

Let's reverse engineer:

  • We now want to call the constructor, like try 2:

    from names import NameEmployee
    NameEmployee().first_name(x='John')
    
  • Now we want to alias:

    from names import NameEmployee as ne
    ne().first_name(x='John')
    

    (Remember that aliasing is simply name replacement)

  • Now if you want you can separate the object to a new variable:

    from names import NameEmployee as ne
    name_employee = ne()
    name_employee.first_name(x='John')
    

Upvotes: 2

Seth
Seth

Reputation: 2369

In the first example, you are not instantiating a NameEmployee object, so it cannot automatically pass a self object to the function. The second example is the correct way of using classes the way that you want to.

Upvotes: 0

Related Questions