1

I need to access a variable which is set in a nested function. I'm reading this variable data from another thread. What is the best way to obtain the data without doing any scope violation?

Here is the code snippet,

class main(object):
    def sub_fun(self):
        def inner_fun(self):
            self.var = 10
        inner_fun(self)

p = main().sub_fun()

Now how to access the var attribute of p?

3
  • 2
    That var literally doesn't exist. It's only created once the inner_fun function is called, and you haven't called that function anywhere. Commented Oct 31, 2018 at 5:21
  • Yes that's one more question I have, I tried to invoke the function by "p.sub_fun().inner_fun()" it didn't work is there any ways to access by "p.sub_fun().inner_fun().var" Commented Oct 31, 2018 at 5:40
  • Consider adding a return value to your function and fixing your indentation. Commented Oct 31, 2018 at 6:48

2 Answers 2

2
class main(object):
    def sub_fun(self):
        def inner_fun(self):
          self.var = 10
p = main()

You cannot access the nested function's variable because its a closure & is accessible only to the immediate parent. var is only accessible by inner_fun. See below for a different implementation.

class main(object):
def outer_function(self):

    def inner_function(self):
        self.x = 10
        return self.x

    out = inner_function(self) # Accessing the inner function
    return out 

p = main()
q = p.outer_function() 
print(q)

If there is a need for a class object or a parent function to access a variable inside a child nested function, then the variable should be hoisted to the outer scope by returning it. Otherwise the scope of the variable will reside only in the so called child nested function.

Sign up to request clarification or add additional context in comments.

Comments

1

The problem is that main.sub_fun returns None. There are two simple workarounds:

  1. Just store a reference to the item you create before calling the method:

    p = main()
    p.sub_fun()
    print(p.var)
    

    This is the best option in my opinion.

  2. If you really want the one line version to work, return self from sub_fun:

    def sub_fun(self):
        def inner_fun():
            self.var = 10
        inner_fun()
        return self
    
    print(main().sub_fun().var)
    

In neither case do you need to pass self to inner_fun. It will always look into the outer scope when the local name is not found. #2 shows an example of this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.