Home > Mobile >  Using an Object based Function within a normal Function in Python
Using an Object based Function within a normal Function in Python

Time:05-18

I am trying to call an object oriented function, within a (normal) function. I use the (normal) function directly with the object. Firstly, the fact that the outer (normal) function accepts the object seems somewhat counter-intuitive to me. Secondly, the error I get is that the inner object based function is not able to get an object as reference. Here is the code:

class Node:
 def __init__(self, time):
    self.time = time


# list to create objects of class Node
sequence = []
for i in range(5): sequence.append(Node(i * 5))


# object based function, created outside the class, and linked to it
def get_time(self):
    return self.time

Node.get_time = get_time()

# output array
arr = [0 for i in range(5)]

# non-object based function, uses object based function to populate arr
def getter(x):
    arr[x] = get_time()

# implementation
for y in range(5):
    sequence[y].getter(y)

for z in range(5): print(arr[z])

The error I get is - TypeError: get_time() missing 1 required positional argument: 'self' Any clarification is appreciated!

CodePudding user response:

This does everything your code appears to try to do:

class Node:
    def __init__(self, time):
        self.time = time

    def get_time(self):
        return self.time


sequence = [Node(i * 5) for i in range(5)]

arr = [node.get_time() for node in sequence]

print(arr)

However, although you would normally define a method (a function that's part of a class and operates on instances of that class) like the example above, you can define it later as well, although you generally don't need to.

Such a function will get the object it operates on passed as the first argument, which is why get_time has self as the first parameter - it could be called anything, but self is the convention in Python.

So, this does the same:

class Node:
    def __init__(self, time):
        self.time = time


def get_time(self):
    return self.time


# note: "get_time", not "get_time()", assigning the function itself, not the result
Node.get_time = get_time

sequence = [Node(i * 5) for i in range(5)]

arr = [node.get_time() for node in sequence]

print(arr)

However, it may give you problems if you later inherit from Node, and your editor may not always be aware that get_time is now a method of Node and generate warnings. Don't do this unless you must.

To answer your question: because get_item is assigned to Node.get_item and it is a function, it now works as a method on that class, an thus it gets called with an object of the class Node as its first argument, when called on that object.

If you want a function to access the object and its contents (attributes and methods), it needs to know about the object and its class, but it can just access it like this:

def get_all_times(nodes):
    return [node.get_time() for node in nodes]


arr = get_all_times(sequence)

Wherever you have access to an instance of the class, it will have the attributes and methods defined on it, you don't need anything special to access them (other than knowing they are there).

  • Related