-1

I have this start.py:

# start.py

class Start:
    def __init__(self):
        self.mylist = []

    def run(self):
        # some code

Executing its run() method will at some point invoke the put_item(obj) method in moduleX.py:

# moduleX.py

def put_item(obj):
    # what should I write here

run() is NOT the direct caller of put_item(obj). In fact, from run() to put_item(obj) the execution is quite complex and involves a lot of other invocations.

My problem is, when put_item(obj) is called, can I directly add the value of obj back to mylist in the class Start? For example:

s = Start()
# suppose during this execution, put_item(obj) has been 
# invoked 3 times, with obj equals to 1, 2, 3 each time
s.run() 
print(s.mylist) # I want it to be [1,2,3]

UPDATE:

  1. From run() to put_item(obj) the execution involves heavy usages of 3rd-party modules and function calls that I have no control over. In other words, the execution inbetween run() to put_item(obj) is like a blackbox to me, and this execution leads to the value of obj that I'm interested in.

  2. obj is consumed in put_item(obj) in moduleX.py, which is also a 3rd-party module. put_item(obj) originally has GUI code that displays obj in a fancy way. However, I want to modify its original behavior such that I can add obj to mylist in class Start and use mylist later in my own way.

  3. Therefore, I cannot pass Start reference along the call chain to put_item since I don't know the call chain and I simply cannot modify it. Also, I cannot change the method signatures in moduleX.py otherwise I'll break the original API. What I can change is the content of put_item(obj) and the start.py.

Ida
  • 2,919
  • 3
  • 32
  • 40

2 Answers2

0

Simply make put_item return the item you want to put in your instance:

def put_item():
    # some code
    return 42

class Start:
    def __init__(self):
        self.mylist = []

    def run(self):
        # some code
        self.mylist.append(put_item())

s = Start()
s.run()
print(s.mylist)

Prints:

[42]
Lynn
  • 10,425
  • 43
  • 75
0

Yes, you can, but you will have to propagate a reference to your Start object's list down the call stack to put_item(). Your Start object can then add items to the list. It does not have to know or care that the object it is being passed is in the Start. It can just blindly add them.

For example (Ideone):

class Start:
    def __init__(self):
        self.mylist = []

    def run(self):
        foo(self.mylist)
        print(self.mylist)

def foo(listRef):
    bar(listRef)

def bar(listRef):
    someItem = "Hello, World!"
    put_item(listRef, someItem)

def put_item(listRef, obj):
    listRef.append(obj)

x = Start()
x.run()

Of course, you'll get the appropriate runtime error if the thing you pass to foo turns out not to be a list.

George Hilliard
  • 15,402
  • 9
  • 58
  • 96