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).